Bug 1714138 - Remove AnimatedGeometryRoot. r=mstange

Differential Revision: https://phabricator.services.mozilla.com/D124154
This commit is contained in:
Matt Woodrow 2021-09-06 23:12:05 +00:00
parent e060744ad1
commit 4588b30e2b
5 changed files with 28 additions and 493 deletions

View File

@ -77,8 +77,7 @@ static void PrintDisplayItemTo(nsDisplayListBuilder* aBuilder,
aStream << nsPrintfCString(
"%s p=0x%p f=0x%p(%s) key=%d %sbounds(%d,%d,%d,%d) "
"componentAlpha(%d,%d,%d,%d) clip(%s) asr(%s) clipChain(%s)%s "
"agr=0x%p",
"componentAlpha(%d,%d,%d,%d) clip(%s) asr(%s) clipChain(%s)%s ",
aItem->Name(), aItem, (void*)f, NS_ConvertUTF16toUTF8(contentData).get(),
aItem->GetPerFrameKey(),
(aItem->ZIndex() ? nsPrintfCString("z=%d ", aItem->ZIndex()).get() : ""),
@ -86,8 +85,7 @@ static void PrintDisplayItemTo(nsDisplayListBuilder* aBuilder,
component.width, component.height, clip.ToString().get(),
ActiveScrolledRoot::ToString(aItem->GetActiveScrolledRoot()).get(),
DisplayItemClipChain::ToString(aItem->GetClipChain()).get(),
aItem->IsUniform(aBuilder) ? " uniform" : "",
aItem->GetAnimatedGeometryRoot()->mFrame);
aItem->IsUniform(aBuilder) ? " uniform" : "");
for (auto iter = opaque.RectIter(); !iter.Done(); iter.Next()) {
const nsRect& r = iter.Get();

View File

@ -4354,9 +4354,6 @@ nsRect ScrollFrameHelper::RestrictToRootDisplayPort(
bool ScrollFrameHelper::DecideScrollableLayer(
nsDisplayListBuilder* aBuilder, nsRect* aVisibleRect, nsRect* aDirtyRect,
bool aSetBase, bool* aDirtyRectHasBeenOverriden) {
// Save and check if this changes so we can recompute the current agr.
bool oldWillBuildScrollableLayer = mWillBuildScrollableLayer;
nsIContent* content = mOuter->GetContent();
// For hit testing purposes with fission we want to create a
// minimal display port for every scroll frame that could be active. (We only
@ -4477,13 +4474,6 @@ bool ScrollFrameHelper::DecideScrollableLayer(
mWillBuildScrollableLayer = usingDisplayPort ||
nsContentUtils::HasScrollgrab(content) ||
mZoomableByAPZ;
// The cached animated geometry root for the display builder is out of
// date if we just introduced a new animated geometry root.
if (oldWillBuildScrollableLayer != mWillBuildScrollableLayer) {
aBuilder->RecomputeCurrentAnimatedGeometryRoot();
}
return mWillBuildScrollableLayer;
}

View File

@ -1169,9 +1169,7 @@ bool RetainedDisplayListBuilder::ProcessFrame(
// TODO: There is almost certainly a faster way of doing this, probably can be
// combined with the ancestor walk for TransformFrameRectToAncestor.
AnimatedGeometryRoot* agr =
aBuilder->FindAnimatedGeometryRootFor(aFrame)->GetAsyncAGR();
nsIFrame* agrFrame = agr ? agr->mFrame : nullptr;
nsIFrame* agrFrame = aBuilder->FindAnimatedGeometryRootFrameFor(aFrame);
CRR_LOG("Processing frame %p with agr %p\n", aFrame, agr->mFrame);

View File

@ -619,11 +619,7 @@ nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame,
mCurrentContainerASR(nullptr),
mCurrentFrame(aReferenceFrame),
mCurrentReferenceFrame(aReferenceFrame),
mRootAGR(AnimatedGeometryRoot::CreateAGRForFrame(
aReferenceFrame, nullptr, true, aRetainingDisplayList)),
mCurrentAGR(mRootAGR),
mBuildingExtraPagesForPageNum(0),
mUsedAGRBudget(0),
mDirtyRect(-1, -1, -1, -1),
mGlassDisplayItem(nullptr),
mHasGlassItemDuringPartial(false),
@ -708,9 +704,6 @@ static PresShell* GetFocusedPresShell() {
void nsDisplayListBuilder::BeginFrame() {
nsCSSRendering::BeginFrameTreesLocked();
mCurrentAGR = mRootAGR;
mFrameToAnimatedGeometryRootMap.InsertOrUpdate(mReferenceFrame,
RefPtr{mRootAGR});
mIsPaintingToWindow = false;
mUseHighQualityScaling = false;
@ -743,8 +736,6 @@ void nsDisplayListBuilder::BeginFrame() {
void nsDisplayListBuilder::EndFrame() {
NS_ASSERTION(!mInInvalidSubtree,
"Someone forgot to cleanup mInInvalidSubtree!");
mFrameToAnimatedGeometryRootMap.Clear();
mAGRBudgetSet.Clear();
mActiveScrolledRoots.Clear();
mEffectsUpdates.Clear();
FreeClipChains();
@ -828,83 +819,6 @@ bool nsDisplayListBuilder::NeedToForceTransparentSurfaceForItem(
return aItem == mGlassDisplayItem;
}
AnimatedGeometryRoot* nsDisplayListBuilder::WrapAGRForFrame(
nsIFrame* aAnimatedGeometryRoot, bool aIsAsync,
AnimatedGeometryRoot* aParent /* = nullptr */) {
DebugOnly<bool> dummy;
MOZ_ASSERT(IsAnimatedGeometryRoot(aAnimatedGeometryRoot, dummy) == AGR_YES);
RefPtr<AnimatedGeometryRoot> result =
mFrameToAnimatedGeometryRootMap.Get(aAnimatedGeometryRoot);
if (!result) {
MOZ_ASSERT(nsLayoutUtils::IsAncestorFrameCrossDocInProcess(
RootReferenceFrame(), aAnimatedGeometryRoot));
RefPtr<AnimatedGeometryRoot> parent = aParent;
if (!parent) {
nsIFrame* parentFrame =
nsLayoutUtils::GetCrossDocParentFrameInProcess(aAnimatedGeometryRoot);
if (parentFrame) {
bool isAsync;
nsIFrame* parentAGRFrame =
FindAnimatedGeometryRootFrameFor(parentFrame, isAsync);
parent = WrapAGRForFrame(parentAGRFrame, isAsync);
}
}
result = AnimatedGeometryRoot::CreateAGRForFrame(
aAnimatedGeometryRoot, parent, aIsAsync, IsRetainingDisplayList());
mFrameToAnimatedGeometryRootMap.InsertOrUpdate(aAnimatedGeometryRoot,
RefPtr{result});
}
MOZ_ASSERT(!aParent || result->mParentAGR == aParent);
return result;
}
AnimatedGeometryRoot* nsDisplayListBuilder::AnimatedGeometryRootForASR(
const ActiveScrolledRoot* aASR) {
if (!aASR) {
return GetRootAnimatedGeometryRoot();
}
nsIFrame* scrolledFrame = aASR->mScrollableFrame->GetScrolledFrame();
return FindAnimatedGeometryRootFor(scrolledFrame);
}
AnimatedGeometryRoot* nsDisplayListBuilder::FindAnimatedGeometryRootFor(
nsIFrame* aFrame) {
if (!IsPaintingToWindow()) {
return mRootAGR;
}
if (aFrame == mCurrentFrame) {
return mCurrentAGR;
}
RefPtr<AnimatedGeometryRoot> result =
mFrameToAnimatedGeometryRootMap.Get(aFrame);
if (result) {
return result;
}
bool isAsync;
nsIFrame* agrFrame = FindAnimatedGeometryRootFrameFor(aFrame, isAsync);
result = WrapAGRForFrame(agrFrame, isAsync);
return result;
}
AnimatedGeometryRoot* nsDisplayListBuilder::FindAnimatedGeometryRootFor(
nsDisplayItem* aItem) {
if (aItem->ShouldFixToViewport(this)) {
// Make its active scrolled root be the active scrolled root of
// the enclosing viewport, since it shouldn't be scrolled by scrolled
// frames in its document. InvalidateFixedBackgroundFramesFromList in
// nsGfxScrollFrame will not repaint this item when scrolling occurs.
nsIFrame* viewportFrame = nsLayoutUtils::GetClosestFrameOfType(
aItem->Frame(), LayoutFrameType::Viewport, RootReferenceFrame());
if (viewportFrame) {
return FindAnimatedGeometryRootFor(viewportFrame);
}
}
return FindAnimatedGeometryRootFor(aItem->Frame());
}
void nsDisplayListBuilder::SetIsRelativeToLayoutViewport() {
mIsRelativeToLayoutViewport = true;
UpdateShouldBuildAsyncZoomContainer();
@ -1266,8 +1180,6 @@ void nsDisplayListBuilder::LeavePresShell(const nsIFrame* aReferenceFrame,
}
mIsInChromePresContext = pc->IsChrome();
} else {
mCurrentAGR = mRootAGR;
for (uint32_t i = 0; i < mFramesMarkedForDisplayIfVisible.Length(); ++i) {
UnmarkFrameForDisplayIfVisible(mFramesMarkedForDisplayIfVisible[i]);
}
@ -1629,40 +1541,35 @@ static bool IsStickyFrameActive(nsDisplayListBuilder* aBuilder,
return sf->IsScrollingActive();
}
nsDisplayListBuilder::AGRState nsDisplayListBuilder::IsAnimatedGeometryRoot(
nsIFrame* aFrame, bool& aIsAsync, nsIFrame** aParent) {
// We can return once we know that this frame is an AGR, and we're either
// async, or sure that none of the later conditions might make us async.
// The exception to this is when IsPaintingToWindow() == false.
aIsAsync = false;
bool nsDisplayListBuilder::IsAnimatedGeometryRoot(nsIFrame* aFrame,
nsIFrame** aParent) {
if (aFrame == mReferenceFrame) {
aIsAsync = true;
return AGR_YES;
return true;
}
if (!IsPaintingToWindow()) {
if (aParent) {
*aParent = nsLayoutUtils::GetCrossDocParentFrameInProcess(aFrame);
}
return AGR_NO;
return false;
}
nsIFrame* parent = nsLayoutUtils::GetCrossDocParentFrameInProcess(aFrame);
if (!parent) {
aIsAsync = true;
return AGR_YES;
return true;
}
*aParent = parent;
if (aFrame->StyleDisplay()->mPosition == StylePositionProperty::Sticky &&
IsStickyFrameActive(this, aFrame, parent)) {
aIsAsync = true;
return AGR_YES;
return true;
}
if (aFrame->IsTransformed()) {
aIsAsync = EffectCompositor::HasAnimationsForCompositor(
aFrame, DisplayItemType::TYPE_TRANSFORM);
return AGR_YES;
if (EffectCompositor::HasAnimationsForCompositor(
aFrame, DisplayItemType::TYPE_TRANSFORM)) {
return true;
}
}
LayoutFrameType parentType = parent->Type();
@ -1671,95 +1578,28 @@ nsDisplayListBuilder::AGRState nsDisplayListBuilder::IsAnimatedGeometryRoot(
nsIScrollableFrame* sf = do_QueryFrame(parent);
if (sf->GetScrolledFrame() == aFrame && sf->IsScrollingActive()) {
MOZ_ASSERT(!aFrame->IsTransformed());
aIsAsync = sf->IsMaybeAsynchronouslyScrolled();
return AGR_YES;
return sf->IsMaybeAsynchronouslyScrolled();
}
}
// Treat the slider thumb as being as an active scrolled root when it wants
// its own layer so that it can move without repainting.
if (parentType == LayoutFrameType::Slider) {
auto* sf = static_cast<nsSliderFrame*>(parent)->GetScrollFrame();
if (sf && sf->IsScrollingActive()) {
return AGR_YES;
}
}
if (nsLayoutUtils::IsPopup(aFrame)) {
return AGR_YES;
}
if (ActiveLayerTracker::IsOffsetStyleAnimated(aFrame)) {
const bool inBudget = AddToAGRBudget(aFrame);
if (inBudget) {
return AGR_YES;
}
}
if (!aFrame->GetParent() &&
DisplayPortUtils::ViewportHasDisplayPort(aFrame->PresContext())) {
// Viewport frames in a display port need to be animated geometry roots
// for background-attachment:fixed elements.
return AGR_YES;
}
// Fixed-pos frames are parented by the viewport frame, which has no parent.
if (DisplayPortUtils::IsFixedPosFrameInDisplayPort(aFrame)) {
return AGR_YES;
}
if (aParent) {
*aParent = parent;
}
return AGR_NO;
return false;
}
nsIFrame* nsDisplayListBuilder::FindAnimatedGeometryRootFrameFor(
nsIFrame* aFrame, bool& aIsAsync) {
nsIFrame* aFrame) {
MOZ_ASSERT(nsLayoutUtils::IsAncestorFrameCrossDocInProcess(
RootReferenceFrame(), aFrame));
nsIFrame* cursor = aFrame;
while (cursor != RootReferenceFrame()) {
nsIFrame* next;
if (IsAnimatedGeometryRoot(cursor, aIsAsync, &next) == AGR_YES) {
if (IsAnimatedGeometryRoot(cursor, &next)) {
return cursor;
}
cursor = next;
}
// Root frame is always an async agr.
aIsAsync = true;
return cursor;
}
void nsDisplayListBuilder::RecomputeCurrentAnimatedGeometryRoot() {
bool isAsync;
if (*mCurrentAGR != mCurrentFrame &&
IsAnimatedGeometryRoot(const_cast<nsIFrame*>(mCurrentFrame), isAsync) ==
AGR_YES) {
AnimatedGeometryRoot* oldAGR = mCurrentAGR;
mCurrentAGR = WrapAGRForFrame(const_cast<nsIFrame*>(mCurrentFrame), isAsync,
mCurrentAGR);
// Iterate the AGR cache and look for any objects that reference the old AGR
// and check to see if they need to be updated. AGRs can be in the cache
// multiple times, so we may end up doing the work multiple times for AGRs
// that don't change.
for (const RefPtr<AnimatedGeometryRoot>& cached :
mFrameToAnimatedGeometryRootMap.Values()) {
if (cached->mParentAGR == oldAGR && cached != mCurrentAGR) {
// It's possible that this cached AGR struct that has the old AGR as a
// parent should instead have mCurrentFrame has a parent.
nsIFrame* parent = FindAnimatedGeometryRootFrameFor(*cached, isAsync);
MOZ_ASSERT(parent == mCurrentFrame || parent == *oldAGR);
if (parent == mCurrentFrame) {
cached->mParentAGR = mCurrentAGR;
}
}
}
}
}
static nsRect ApplyAllClipNonRoundedIntersection(
const DisplayItemClipChain* aClipChain, const nsRect& aRect) {
nsRect result = aRect;
@ -1891,7 +1731,6 @@ void nsDisplayListBuilder::AddSizeOfExcludingThis(nsWindowSizes& aSizes) const {
MallocSizeOf mallocSizeOf = aSizes.mState.mMallocSizeOf;
n += mDocumentWillChangeBudgets.ShallowSizeOfExcludingThis(mallocSizeOf);
n += mFrameWillChangeBudgets.ShallowSizeOfExcludingThis(mallocSizeOf);
n += mAGRBudgetSet.ShallowSizeOfExcludingThis(mallocSizeOf);
n += mEffectsUpdates.ShallowSizeOfExcludingThis(mallocSizeOf);
n += mWindowExcludeGlassRegion.SizeOfExcludingThis(mallocSizeOf);
n += mRetainedWindowDraggingRegion.SizeOfExcludingThis(mallocSizeOf);
@ -2086,40 +1925,6 @@ void nsDisplayListBuilder::ClearWillChangeBudgets() {
mDocumentWillChangeBudgets.Clear();
}
#ifdef MOZ_GFX_OPTIMIZE_MOBILE
const float gAGRBudgetAreaMultiplier = 0.3;
#else
const float gAGRBudgetAreaMultiplier = 3.0;
#endif
bool nsDisplayListBuilder::AddToAGRBudget(nsIFrame* aFrame) {
if (mAGRBudgetSet.Contains(aFrame)) {
return true;
}
const nsPresContext* presContext =
aFrame->PresContext()->GetRootPresContext();
if (!presContext) {
return false;
}
const nsRect area = presContext->GetVisibleArea();
const uint32_t budgetLimit =
gAGRBudgetAreaMultiplier *
nsPresContext::AppUnitsToIntCSSPixels(area.width) *
nsPresContext::AppUnitsToIntCSSPixels(area.height);
const uint32_t cost = GetLayerizationCost(aFrame->GetSize());
const bool onBudget = mUsedAGRBudget + cost < budgetLimit;
if (onBudget) {
mUsedAGRBudget += cost;
mAGRBudgetSet.Insert(aFrame);
}
return onBudget;
}
void nsDisplayListBuilder::EnterSVGEffectsContents(
nsIFrame* aEffectsFrame, nsDisplayList* aHoistedItemsStorage) {
MOZ_ASSERT(aHoistedItemsStorage);
@ -2761,12 +2566,6 @@ nsDisplayItem::nsDisplayItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
}
aBuilder->FindReferenceFrameFor(aFrame, &mToReferenceFrame);
// This can return the wrong result if the item override
// ShouldFixToViewport(), the item needs to set it again in its constructor.
mAnimatedGeometryRoot = aBuilder->FindAnimatedGeometryRootFor(aFrame);
MOZ_ASSERT(nsLayoutUtils::IsAncestorFrameCrossDocInProcess(
aBuilder->RootReferenceFrame(), *mAnimatedGeometryRoot),
"Bad");
NS_ASSERTION(
aBuilder->GetVisibleRect().width >= 0 || !aBuilder->IsForPainting(),
"visible rect not set");
@ -3095,9 +2894,6 @@ nsDisplayBackgroundImage::nsDisplayBackgroundImage(
mBounds = GetBoundsInternal(aInitData.builder, aFrameForBounds);
if (mShouldFixToViewport) {
mAnimatedGeometryRoot =
aInitData.builder->FindAnimatedGeometryRootFor(this);
// Expand the item's visible rect to cover the entire bounds, limited to the
// viewport rect. This is necessary because the background's clip can move
// asynchronously.
@ -5419,14 +5215,6 @@ nsDisplayOwnLayer::nsDisplayOwnLayer(
mForceActive(aForceActive),
mWrAnimationId(0) {
MOZ_COUNT_CTOR(nsDisplayOwnLayer);
// For scroll thumb layers, override the AGR to be the thumb's AGR rather
// than the AGR for mFrame (which is the slider frame).
if (IsScrollThumbLayer()) {
if (nsIFrame* thumbFrame = nsIFrame::GetChildXULBox(mFrame)) {
mAnimatedGeometryRoot = aBuilder->FindAnimatedGeometryRootFor(thumbFrame);
}
}
}
bool nsDisplayOwnLayer::IsScrollThumbLayer() const {
@ -5593,13 +5381,6 @@ nsDisplaySubDocument::nsDisplaySubDocument(nsDisplayListBuilder* aBuilder,
mSubDocFrame(aSubDocFrame) {
MOZ_COUNT_CTOR(nsDisplaySubDocument);
// The SubDocument display item is conceptually outside the viewport frame,
// so in cases where the viewport frame is an AGR, the SubDocument's AGR
// should be not the viewport frame itself, but its parent AGR.
if (*mAnimatedGeometryRoot == mFrame && mAnimatedGeometryRoot->mParentAGR) {
mAnimatedGeometryRoot = mAnimatedGeometryRoot->mParentAGR;
}
if (mSubDocFrame && mSubDocFrame != mFrame) {
mSubDocFrame->AddDisplayItem(this);
}
@ -5693,7 +5474,6 @@ nsDisplayFixedPosition::nsDisplayFixedPosition(
mContainerASR(aContainerASR),
mIsFixedBackground(false) {
MOZ_COUNT_CTOR(nsDisplayFixedPosition);
Init(aBuilder);
}
nsDisplayFixedPosition::nsDisplayFixedPosition(nsDisplayListBuilder* aBuilder,
@ -5704,14 +5484,6 @@ nsDisplayFixedPosition::nsDisplayFixedPosition(nsDisplayListBuilder* aBuilder,
mContainerASR(nullptr), // XXX maybe this should be something?
mIsFixedBackground(true) {
MOZ_COUNT_CTOR(nsDisplayFixedPosition);
Init(aBuilder);
}
void nsDisplayFixedPosition::Init(nsDisplayListBuilder* aBuilder) {
mAnimatedGeometryRootForScrollMetadata = mAnimatedGeometryRoot;
if (ShouldFixToViewport(aBuilder)) {
mAnimatedGeometryRoot = aBuilder->FindAnimatedGeometryRootFor(this);
}
}
ScrollableLayerGuid::ViewID nsDisplayFixedPosition::GetScrollTargetId() {
@ -6249,8 +6021,6 @@ nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder,
const nsRect& aChildrenBuildingRect)
: nsPaintedDisplayItem(aBuilder, aFrame),
mTransform(Some(Matrix4x4())),
mAnimatedGeometryRootForChildren(mAnimatedGeometryRoot),
mAnimatedGeometryRootForScrollMetadata(mAnimatedGeometryRoot),
mChildrenBuildingRect(aChildrenBuildingRect),
mPrerenderDecision(PrerenderDecision::No),
mIsTransformSeparator(true),
@ -6265,8 +6035,6 @@ nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder,
const nsRect& aChildrenBuildingRect,
PrerenderDecision aPrerenderDecision)
: nsPaintedDisplayItem(aBuilder, aFrame),
mAnimatedGeometryRootForChildren(mAnimatedGeometryRoot),
mAnimatedGeometryRootForScrollMetadata(mAnimatedGeometryRoot),
mChildrenBuildingRect(aChildrenBuildingRect),
mPrerenderDecision(aPrerenderDecision),
mIsTransformSeparator(false),
@ -6282,8 +6050,6 @@ nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder,
const nsRect& aChildrenBuildingRect,
decltype(WithTransformGetter))
: nsPaintedDisplayItem(aBuilder, aFrame),
mAnimatedGeometryRootForChildren(mAnimatedGeometryRoot),
mAnimatedGeometryRootForScrollMetadata(mAnimatedGeometryRoot),
mChildrenBuildingRect(aChildrenBuildingRect),
mPrerenderDecision(PrerenderDecision::No),
mIsTransformSeparator(false),
@ -6314,32 +6080,6 @@ void nsDisplayTransform::SetReferenceFrameToAncestor(
nsIFrame* outerFrame = nsLayoutUtils::GetCrossDocParentFrameInProcess(mFrame);
const nsIFrame* referenceFrame = aBuilder->FindReferenceFrameFor(outerFrame);
mToReferenceFrame = mFrame->GetOffsetToCrossDoc(referenceFrame);
if (DisplayPortUtils::IsFixedPosFrameInDisplayPort(mFrame)) {
// This is an odd special case. If we are both IsFixedPosFrameInDisplayPort
// and transformed that we are our own AGR parent.
// We want our frame to be our AGR because FrameLayerBuilder uses our AGR to
// determine if we are inside a fixed pos subtree. If we use the outer AGR
// from outside the fixed pos subtree FLB can't tell that we are fixed pos.
mAnimatedGeometryRoot = mAnimatedGeometryRootForChildren;
} else if (mFrame->StyleDisplay()->mPosition ==
StylePositionProperty::Sticky &&
IsStickyFrameActive(aBuilder, mFrame, nullptr)) {
// Similar to the IsFixedPosFrameInDisplayPort case we are our own AGR.
// We are inside the sticky position, so our AGR is the sticky positioned
// frame, which is our AGR, not the parent AGR.
mAnimatedGeometryRoot = mAnimatedGeometryRootForChildren;
} else if (mAnimatedGeometryRoot->mParentAGR) {
mAnimatedGeometryRootForScrollMetadata = mAnimatedGeometryRoot->mParentAGR;
if (!MayBeAnimated(aBuilder)) {
// If we're an animated transform then we want the same AGR as our
// children so that FrameLayerBuilder knows that this layer moves with the
// transform and won't compute occlusions. If we're not animated then use
// our parent AGR so that inactive transform layers can go in the same
// PaintedLayer as surrounding content.
mAnimatedGeometryRoot = mAnimatedGeometryRoot->mParentAGR;
}
}
}
void nsDisplayTransform::Init(nsDisplayListBuilder* aBuilder,
@ -7608,8 +7348,6 @@ nsDisplayPerspective::nsDisplayPerspective(nsDisplayListBuilder* aBuilder,
mList.AppendToTop(aList);
MOZ_ASSERT(mList.Count() == 1);
MOZ_ASSERT(mList.GetTop()->GetType() == DisplayItemType::TYPE_TRANSFORM);
mAnimatedGeometryRoot = aBuilder->FindAnimatedGeometryRootFor(
mFrame->GetClosestFlattenedTreeAncestorPrimaryFrame());
}
void nsDisplayPerspective::Paint(nsDisplayListBuilder* aBuilder,
@ -8904,7 +8642,6 @@ nsDisplayListBuilder::AutoBuildingDisplayList::AutoBuildingDisplayList(
mPrevAdditionalOffset(aBuilder->mAdditionalOffset),
mPrevVisibleRect(aBuilder->mVisibleRect),
mPrevDirtyRect(aBuilder->mDirtyRect),
mPrevAGR(aBuilder->mCurrentAGR),
mPrevCompositorHitTestInfo(aBuilder->mCompositorHitTestInfo),
mPrevAncestorHasApzAwareEventHandler(
aBuilder->mAncestorHasApzAwareEventHandler),
@ -8921,21 +8658,6 @@ nsDisplayListBuilder::AutoBuildingDisplayList::AutoBuildingDisplayList(
aForChild, &aBuilder->mCurrentOffsetToReferenceFrame);
}
bool isAsync;
mCurrentAGRState = aBuilder->IsAnimatedGeometryRoot(aForChild, isAsync);
if (aBuilder->mCurrentFrame == aForChild->GetParent()) {
if (mCurrentAGRState == AGR_YES) {
aBuilder->mCurrentAGR =
aBuilder->WrapAGRForFrame(aForChild, isAsync, aBuilder->mCurrentAGR);
}
} else if (aBuilder->mCurrentFrame != aForChild) {
aBuilder->mCurrentAGR = aBuilder->FindAnimatedGeometryRootFor(aForChild);
}
MOZ_ASSERT(nsLayoutUtils::IsAncestorFrameCrossDocInProcess(
aBuilder->RootReferenceFrame(), *aBuilder->mCurrentAGR));
// If aForChild is being visited from a frame other than it's ancestor frame,
// mInInvalidSubtree will need to be recalculated the slow way.
if (aForChild == mPrevFrame || GetAncestorFor(aForChild) == mPrevFrame) {

View File

@ -152,97 +152,6 @@ enum class DisplayListArenaObjectId {
* reference frame for their frame subtrees.
*/
/**
* Represents a frame that is considered to have (or will have) "animated
* geometry" for itself and descendant frames.
*
* 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 PaintedLayers,
* so that we can animate the geometry root by changing its transform (either on
* the main thread or in the compositor).
*
* nsDisplayListBuilder constructs a tree of these (for fast traversals) and
* assigns one for each display item.
*
* The animated geometry root for a display item is required to be a descendant
* (or equal to) the item's ReferenceFrame(), which means that we will fall back
* to returning aItem->ReferenceFrame() when we can't find another animated
* geometry root.
*
* The animated geometry root isn't strongly defined for a frame as transforms
* and background-attachment:fixed can cause it to vary between display items
* for a given frame.
*/
struct AnimatedGeometryRoot {
static already_AddRefed<AnimatedGeometryRoot> CreateAGRForFrame(
nsIFrame* aFrame, AnimatedGeometryRoot* aParent, bool aIsAsync,
bool aIsRetained) {
RefPtr<AnimatedGeometryRoot> result;
if (aIsRetained) {
result = aFrame->GetProperty(AnimatedGeometryRootCache());
}
if (result) {
result->mParentAGR = aParent;
result->mIsAsync = aIsAsync;
} else {
result = new AnimatedGeometryRoot(aFrame, aParent, aIsAsync, aIsRetained);
}
return result.forget();
}
operator nsIFrame*() { return mFrame; }
nsIFrame* operator->() const { return mFrame; }
AnimatedGeometryRoot* GetAsyncAGR() {
AnimatedGeometryRoot* agr = this;
while (!agr->mIsAsync && agr->mParentAGR) {
agr = agr->mParentAGR;
}
return agr;
}
NS_INLINE_DECL_REFCOUNTING(AnimatedGeometryRoot)
nsIFrame* mFrame;
RefPtr<AnimatedGeometryRoot> mParentAGR;
bool mIsAsync;
bool mIsRetained;
protected:
static void DetachAGR(AnimatedGeometryRoot* aAGR) {
aAGR->mFrame = nullptr;
aAGR->mParentAGR = nullptr;
NS_RELEASE(aAGR);
}
NS_DECLARE_FRAME_PROPERTY_WITH_DTOR(AnimatedGeometryRootCache,
AnimatedGeometryRoot, DetachAGR)
AnimatedGeometryRoot(nsIFrame* aFrame, AnimatedGeometryRoot* aParent,
bool aIsAsync, bool aIsRetained)
: mFrame(aFrame),
mParentAGR(aParent),
mIsAsync(aIsAsync),
mIsRetained(aIsRetained) {
MOZ_ASSERT(mParentAGR || mIsAsync,
"The root AGR should always be treated as an async AGR.");
if (mIsRetained) {
NS_ADDREF(this);
aFrame->SetProperty(AnimatedGeometryRootCache(), this);
}
}
~AnimatedGeometryRoot() {
if (mFrame && mIsRetained) {
mFrame->RemoveProperty(AnimatedGeometryRootCache());
}
}
};
/**
* An active scrolled root (ASR) is similar to an animated geometry root (AGR).
* The differences are:
@ -395,13 +304,6 @@ class nsDisplayListBuilder {
bool mAllowAsyncAnimation;
};
/**
* A frame can be in one of three states of AGR.
* AGR_NO means the frame is not an AGR for now.
* AGR_YES means the frame is an AGR for now.
*/
enum AGRState { AGR_NO, AGR_YES };
public:
using ViewID = layers::ScrollableLayerGuid::ViewID;
@ -655,11 +557,6 @@ class nsDisplayListBuilder {
return mCurrentOffsetToReferenceFrame;
}
AnimatedGeometryRoot* GetCurrentAnimatedGeometryRoot() { return mCurrentAGR; }
AnimatedGeometryRoot* GetRootAnimatedGeometryRoot() { return mRootAGR; }
void RecomputeCurrentAnimatedGeometryRoot();
void Check() { mPool.Check(); }
/**
@ -1085,8 +982,6 @@ class nsDisplayListBuilder {
mBuilder->mCurrentOffsetToReferenceFrame += aOffset;
}
bool IsAnimatedGeometryRoot() const { return mCurrentAGRState == AGR_YES; }
void RestoreBuildingInvisibleItemsValue() {
mBuilder->mBuildingInvisibleItems = mPrevBuildingInvisibleItems;
}
@ -1097,7 +992,6 @@ class nsDisplayListBuilder {
mBuilder->mCurrentOffsetToReferenceFrame = mPrevOffset;
mBuilder->mVisibleRect = mPrevVisibleRect;
mBuilder->mDirtyRect = mPrevDirtyRect;
mBuilder->mCurrentAGR = mPrevAGR;
mBuilder->mAncestorHasApzAwareEventHandler =
mPrevAncestorHasApzAwareEventHandler;
mBuilder->mBuildingInvisibleItems = mPrevBuildingInvisibleItems;
@ -1108,14 +1002,12 @@ class nsDisplayListBuilder {
private:
nsDisplayListBuilder* mBuilder;
AGRState mCurrentAGRState;
const nsIFrame* mPrevFrame;
const nsIFrame* mPrevReferenceFrame;
nsPoint mPrevOffset;
Maybe<nsPoint> mPrevAdditionalOffset;
nsRect mPrevVisibleRect;
nsRect mPrevDirtyRect;
RefPtr<AnimatedGeometryRoot> mPrevAGR;
gfx::CompositorHitTestInfo mPrevCompositorHitTestInfo;
bool mPrevAncestorHasApzAwareEventHandler;
bool mPrevBuildingInvisibleItems;
@ -1692,13 +1584,6 @@ class nsDisplayListBuilder {
return mBuildingExtraPagesForPageNum;
}
/**
* This is a convenience function to ease the transition until AGRs and ASRs
* are unified.
*/
AnimatedGeometryRoot* AnimatedGeometryRootForASR(
const ActiveScrolledRoot* aASR);
bool HitTestIsForVisibility() const { return mVisibleThreshold.isSome(); }
float VisibilityThreshold() const {
@ -1797,48 +1682,25 @@ class nsDisplayListBuilder {
nsDisplayList* mList;
};
/**
* Returns the nearest ancestor frame to aFrame that is considered to have
* (or will have) animated geometry. This can return aFrame.
*/
nsIFrame* FindAnimatedGeometryRootFrameFor(nsIFrame* aFrame);
private:
bool MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame, nsIFrame* aFrame,
const nsRect& aVisibleRect,
const nsRect& aDirtyRect);
friend class nsDisplayBackgroundImage;
friend struct RetainedDisplayListBuilder;
/**
* Returns whether a frame acts as an animated geometry root, optionally
* returning the next ancestor to check.
*/
AGRState IsAnimatedGeometryRoot(nsIFrame* aFrame, bool& aIsAsync,
nsIFrame** aParent = nullptr);
/**
* Returns the nearest ancestor frame to aFrame that is considered to have
* (or will have) animated geometry. This can return aFrame.
*/
nsIFrame* FindAnimatedGeometryRootFrameFor(nsIFrame* aFrame, bool& aIsAsync);
friend class nsDisplayCanvasBackgroundImage;
friend class nsDisplayBackgroundImage;
friend class nsDisplayFixedPosition;
friend class nsDisplayPerspective;
AnimatedGeometryRoot* FindAnimatedGeometryRootFor(nsDisplayItem* aItem);
friend class nsDisplayItem;
friend class nsDisplayOwnLayer;
friend struct RetainedDisplayListBuilder;
AnimatedGeometryRoot* FindAnimatedGeometryRootFor(nsIFrame* aFrame);
AnimatedGeometryRoot* WrapAGRForFrame(
nsIFrame* aAnimatedGeometryRoot, bool aIsAsync,
AnimatedGeometryRoot* aParent = nullptr);
nsTHashMap<nsIFrame*, RefPtr<AnimatedGeometryRoot>>
mFrameToAnimatedGeometryRootMap;
/**
* Add the current frame to the AGR budget if possible and remember
* the outcome. Subsequent calls will return the same value as
* returned here.
*/
bool AddToAGRBudget(nsIFrame* aFrame);
bool IsAnimatedGeometryRoot(nsIFrame* aFrame, nsIFrame** aParent = nullptr);
struct PresShellState {
PresShell* mPresShell;
@ -1902,9 +1764,6 @@ class nsDisplayListBuilder {
Maybe<nsPoint> mAdditionalOffset;
RefPtr<AnimatedGeometryRoot> mRootAGR;
RefPtr<AnimatedGeometryRoot> mCurrentAGR;
// will-change budget tracker
typedef uint32_t DocumentWillChangeBudget;
nsTHashMap<nsPtrHashKey<const nsPresContext>, DocumentWillChangeBudget>
@ -1917,11 +1776,6 @@ class nsDisplayListBuilder {
uint8_t mBuildingExtraPagesForPageNum;
// Area of animated geometry root budget already allocated
uint32_t mUsedAGRBudget;
// Set of frames already counted in budget
nsTHashSet<nsIFrame*> mAGRBudgetSet;
nsTHashMap<nsPtrHashKey<dom::RemoteBrowser>, dom::EffectsInfo>
mEffectsUpdates;
@ -2390,7 +2244,6 @@ class nsDisplayItem : public nsDisplayItemLink {
mPerFrameIndex(aOther.mPerFrameIndex),
mBuildingRect(aOther.mBuildingRect),
mToReferenceFrame(aOther.mToReferenceFrame),
mAnimatedGeometryRoot(aOther.mAnimatedGeometryRoot),
mActiveScrolledRoot(aOther.mActiveScrolledRoot),
mClipChain(aOther.mClipChain) {
MOZ_COUNT_CTOR(nsDisplayItem);
@ -2808,17 +2661,6 @@ class nsDisplayItem : public nsDisplayItemLink {
*/
virtual const nsIFrame* ReferenceFrameForChildren() const { return nullptr; }
AnimatedGeometryRoot* GetAnimatedGeometryRoot() const {
MOZ_ASSERT(mAnimatedGeometryRoot,
"Must have cached AGR before accessing it!");
return mAnimatedGeometryRoot;
}
virtual struct AnimatedGeometryRoot* AnimatedGeometryRootForScrollMetadata()
const {
return GetAnimatedGeometryRoot();
}
/**
* Checks if this display item (or any children) contains content that might
* be rendered with component alpha (e.g. subpixel antialiasing). Returns the
@ -2953,7 +2795,6 @@ class nsDisplayItem : public nsDisplayItemLink {
// Result of ToReferenceFrame(mFrame), if mFrame is non-null
nsPoint mToReferenceFrame;
RefPtr<AnimatedGeometryRoot> mAnimatedGeometryRoot;
RefPtr<const ActiveScrolledRoot> mActiveScrolledRoot;
RefPtr<const DisplayItemClipChain> mClipChain;
@ -5660,8 +5501,6 @@ class nsDisplayFixedPosition : public nsDisplayOwnLayer {
nsDisplayFixedPosition(nsDisplayListBuilder* aBuilder,
const nsDisplayFixedPosition& aOther)
: nsDisplayOwnLayer(aBuilder, aOther),
mAnimatedGeometryRootForScrollMetadata(
aOther.mAnimatedGeometryRootForScrollMetadata),
mContainerASR(aOther.mContainerASR),
mIsFixedBackground(aOther.mIsFixedBackground) {
MOZ_COUNT_CTOR(nsDisplayFixedPosition);
@ -5685,10 +5524,6 @@ class nsDisplayFixedPosition : public nsDisplayOwnLayer {
return mIsFixedBackground;
}
AnimatedGeometryRoot* AnimatedGeometryRootForScrollMetadata() const override {
return mAnimatedGeometryRootForScrollMetadata;
}
bool CreateWebRenderCommands(
wr::DisplayListBuilder& aBuilder, wr::IpcResourceUpdateQueue& aResources,
const StackingContextHelper& aSc,
@ -5702,10 +5537,8 @@ class nsDisplayFixedPosition : public nsDisplayOwnLayer {
// For background-attachment:fixed
nsDisplayFixedPosition(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
nsDisplayList* aList);
void Init(nsDisplayListBuilder* aBuilder);
ViewID GetScrollTargetId();
RefPtr<AnimatedGeometryRoot> mAnimatedGeometryRootForScrollMetadata;
RefPtr<const ActiveScrolledRoot> mContainerASR;
bool mIsFixedBackground;
@ -6268,10 +6101,6 @@ class nsDisplayTransform : public nsPaintedDisplayItem {
return nsPaintedDisplayItem::ReferenceFrameForChildren();
}
AnimatedGeometryRoot* AnimatedGeometryRootForScrollMetadata() const override {
return mAnimatedGeometryRootForScrollMetadata;
}
const nsRect& GetBuildingRectForChildren() const override {
return mChildrenBuildingRect;
}
@ -6510,8 +6339,6 @@ class nsDisplayTransform : public nsPaintedDisplayItem {
mutable Maybe<Matrix4x4Flagged> mInverseTransform;
// Accumulated transform of ancestors on the preserves-3d chain.
UniquePtr<Matrix4x4> mTransformPreserves3D;
RefPtr<AnimatedGeometryRoot> mAnimatedGeometryRootForChildren;
RefPtr<AnimatedGeometryRoot> mAnimatedGeometryRootForScrollMetadata;
nsRect mChildrenBuildingRect;
mutable RetainedDisplayList mChildren;