зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1342009 - Provide a shortcut in BuildDisplayListForChild. r=mattwoodrow
This commit is contained in:
Родитель
c24d2c4ce4
Коммит
70bcac7cb4
|
@ -977,7 +977,8 @@ nsFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
|
|||
PresContext()->SetBidiEnabled();
|
||||
}
|
||||
|
||||
RemoveStateBits(NS_FRAME_SIMPLE_EVENT_REGIONS);
|
||||
RemoveStateBits(NS_FRAME_SIMPLE_EVENT_REGIONS |
|
||||
NS_FRAME_SIMPLE_DISPLAYLIST);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -2156,8 +2157,10 @@ nsIFrame::GetClipPropClipRect(const nsStyleDisplay* aDisp,
|
|||
* handled by constructing a dedicated nsHTML/XULScrollFrame, set up clipping
|
||||
* for that overflow in aBuilder->ClipState() to clip all containing-block
|
||||
* descendants.
|
||||
*
|
||||
* Return true if clipping was applied.
|
||||
*/
|
||||
static void
|
||||
static bool
|
||||
ApplyOverflowClipping(nsDisplayListBuilder* aBuilder,
|
||||
const nsIFrame* aFrame,
|
||||
const nsStyleDisplay* aDisp,
|
||||
|
@ -2169,7 +2172,7 @@ ApplyOverflowClipping(nsDisplayListBuilder* aBuilder,
|
|||
// is required by comboboxes which make their display text (an inline frame)
|
||||
// have clipping.
|
||||
if (!nsFrame::ShouldApplyOverflowClipping(aFrame, aDisp)) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
nsRect clipRect;
|
||||
bool haveRadii = false;
|
||||
|
@ -2185,6 +2188,7 @@ ApplyOverflowClipping(nsDisplayListBuilder* aBuilder,
|
|||
// XXX border-radius
|
||||
}
|
||||
aClipState.ClipContainingBlockDescendantsExtra(clipRect, haveRadii ? radii : nullptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -2864,6 +2868,45 @@ WrapInWrapList(nsDisplayListBuilder* aBuilder,
|
|||
return item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a frame should be visited for building display list.
|
||||
*/
|
||||
static bool
|
||||
DescendIntoChild(nsDisplayListBuilder* aBuilder, nsIFrame *aChild,
|
||||
const nsRect& aDirty)
|
||||
{
|
||||
nsIFrame* child = aChild;
|
||||
const nsRect& dirty = aDirty;
|
||||
|
||||
if (!(child->GetStateBits() & NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO)) {
|
||||
// No need to descend into child to catch placeholders for visible
|
||||
// positioned stuff. So see if we can short-circuit frame traversal here.
|
||||
|
||||
// We can stop if child's frame subtree's intersection with the
|
||||
// dirty area is empty.
|
||||
// If the child is a scrollframe that we want to ignore, then we need
|
||||
// to descend into it because its scrolled child may intersect the dirty
|
||||
// area even if the scrollframe itself doesn't.
|
||||
// There are cases where the "ignore scroll frame" on the builder is not set
|
||||
// correctly, and so we additionally want to catch cases where the child is
|
||||
// a root scrollframe and we are ignoring scrolling on the viewport.
|
||||
nsIPresShell* shell = child->PresContext()->PresShell();
|
||||
bool keepDescending = child == aBuilder->GetIgnoreScrollFrame() ||
|
||||
(shell->IgnoringViewportScrolling() && child == shell->GetRootScrollFrame());
|
||||
if (!keepDescending) {
|
||||
nsRect childDirty;
|
||||
if (!childDirty.IntersectRect(dirty, child->GetVisualOverflowRect()))
|
||||
return false;
|
||||
// Usually we could set dirty to childDirty now but there's no
|
||||
// benefit, and it can be confusing. It can especially confuse
|
||||
// situations where we're going to ignore a scrollframe's clipping;
|
||||
// we wouldn't want to clip the dirty area to the scrollframe's
|
||||
// bounds in that case.
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
|
||||
nsIFrame* aChild,
|
||||
|
@ -2886,11 +2929,59 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
|
|||
if (child->GetStateBits() & NS_FRAME_TOO_DEEP_IN_FRAME_TREE)
|
||||
return;
|
||||
|
||||
const bool doingShortcut =
|
||||
(child->GetStateBits() & NS_FRAME_SIMPLE_DISPLAYLIST) &&
|
||||
aBuilder->IsPaintingToWindow() &&
|
||||
// This would be changed by the change of preference.
|
||||
aBuilder->IsBuildingLayerEventRegions() &&
|
||||
// Animations may change the value of |HasOpacity()|.
|
||||
!(child->GetContent() &&
|
||||
child->GetContent()->MayHaveAnimations());
|
||||
if (doingShortcut) {
|
||||
// This is the shortcut for frames been handled along the common
|
||||
// path, the most common one of THE COMMON CASE mentioned later.
|
||||
MOZ_ASSERT(child->Type() != LayoutFrameType::Placeholder);
|
||||
MOZ_ASSERT(!aBuilder->GetSelectedFramesOnly() &&
|
||||
!aBuilder->GetIncludeAllOutOfFlows(),
|
||||
"It should be held for painting to window");
|
||||
|
||||
// dirty rect in child-relative coordinates
|
||||
nsRect dirty = aDirtyRect - child->GetOffsetTo(this);
|
||||
if (!DescendIntoChild(aBuilder, child, dirty)) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsDisplayListBuilder::AutoBuildingDisplayList
|
||||
buildingForChild(aBuilder, child, dirty, false);
|
||||
|
||||
CheckForApzAwareEventHandlers(aBuilder, child);
|
||||
|
||||
nsDisplayLayerEventRegions* eventRegions = aBuilder->GetLayerEventRegions();
|
||||
if (eventRegions) {
|
||||
eventRegions->AddFrame(aBuilder, child);
|
||||
}
|
||||
|
||||
child->MarkAbsoluteFramesForDisplayList(aBuilder, dirty);
|
||||
aBuilder->AdjustWindowDraggingRegion(child);
|
||||
child->BuildDisplayList(aBuilder, dirty, aLists);
|
||||
aBuilder->DisplayCaret(child, dirty, aLists.Content());
|
||||
#ifdef DEBUG
|
||||
DisplayDebugBorders(aBuilder, child, aLists);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
bool isSVG = (child->GetStateBits() & NS_FRAME_SVG_LAYOUT);
|
||||
|
||||
// It is raised if the control flow strays off the common path.
|
||||
// The common path is the most common one of THE COMMON CASE
|
||||
// mentioned later.
|
||||
bool awayFromCommonPath = false;
|
||||
|
||||
// true if this is a real or pseudo stacking context
|
||||
bool pseudoStackingContext =
|
||||
(aFlags & DISPLAY_CHILD_FORCE_PSEUDO_STACKING_CONTEXT) != 0;
|
||||
awayFromCommonPath |= pseudoStackingContext;
|
||||
if (!isSVG &&
|
||||
(aFlags & DISPLAY_CHILD_INLINE) &&
|
||||
!child->IsFrameOfType(eLineParticipant)) {
|
||||
|
@ -2898,6 +2989,7 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
|
|||
// it acts like inline-block or inline-table. Therefore it is a
|
||||
// pseudo-stacking-context.
|
||||
pseudoStackingContext = true;
|
||||
awayFromCommonPath = true;
|
||||
}
|
||||
|
||||
// dirty rect in child-relative coordinates
|
||||
|
@ -2938,6 +3030,7 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
|
|||
dirty.SetEmpty();
|
||||
}
|
||||
pseudoStackingContext = true;
|
||||
awayFromCommonPath = true;
|
||||
}
|
||||
|
||||
NS_ASSERTION(!child->IsPlaceholderFrame(),
|
||||
|
@ -2951,31 +3044,9 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
|
|||
if (aBuilder->GetIncludeAllOutOfFlows() &&
|
||||
(child->GetStateBits() & NS_FRAME_OUT_OF_FLOW)) {
|
||||
dirty = child->GetVisualOverflowRect();
|
||||
} else if (!(child->GetStateBits() & NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO)) {
|
||||
// No need to descend into child to catch placeholders for visible
|
||||
// positioned stuff. So see if we can short-circuit frame traversal here.
|
||||
|
||||
// We can stop if child's frame subtree's intersection with the
|
||||
// dirty area is empty.
|
||||
// If the child is a scrollframe that we want to ignore, then we need
|
||||
// to descend into it because its scrolled child may intersect the dirty
|
||||
// area even if the scrollframe itself doesn't.
|
||||
// There are cases where the "ignore scroll frame" on the builder is not set
|
||||
// correctly, and so we additionally want to catch cases where the child is
|
||||
// a root scrollframe and we are ignoring scrolling on the viewport.
|
||||
nsIPresShell* shell = PresContext()->PresShell();
|
||||
bool keepDescending = child == aBuilder->GetIgnoreScrollFrame() ||
|
||||
(shell->IgnoringViewportScrolling() && child == shell->GetRootScrollFrame());
|
||||
if (!keepDescending) {
|
||||
nsRect childDirty;
|
||||
if (!childDirty.IntersectRect(dirty, child->GetVisualOverflowRect()))
|
||||
return;
|
||||
// Usually we could set dirty to childDirty now but there's no
|
||||
// benefit, and it can be confusing. It can especially confuse
|
||||
// situations where we're going to ignore a scrollframe's clipping;
|
||||
// we wouldn't want to clip the dirty area to the scrollframe's
|
||||
// bounds in that case.
|
||||
}
|
||||
awayFromCommonPath = true;
|
||||
} else if (!DescendIntoChild(aBuilder, child, dirty)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// XXX need to have inline-block and inline-table set pseudoStackingContext
|
||||
|
@ -2992,6 +3063,7 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
|
|||
// within the displayport.
|
||||
if (aBuilder->IsPaintingToWindow() && child->TrackingVisibility()) {
|
||||
child->PresContext()->PresShell()->EnsureFrameInApproximatelyVisibleList(child);
|
||||
awayFromCommonPath = true;
|
||||
}
|
||||
|
||||
// Child is composited if it's transformed, partially transparent, or has
|
||||
|
@ -3023,6 +3095,7 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
|
|||
(aFlags & DISPLAY_CHILD_FORCE_STACKING_CONTEXT)) {
|
||||
// If you change this, also change IsPseudoStackingContextFromStyle()
|
||||
pseudoStackingContext = true;
|
||||
awayFromCommonPath = true;
|
||||
}
|
||||
NS_ASSERTION(!isStackingContext || pseudoStackingContext,
|
||||
"Stacking contexts must also be pseudo-stacking-contexts");
|
||||
|
@ -3040,6 +3113,7 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
|
|||
savedOutOfFlowData->mContainingBlockClipChain);
|
||||
asrSetter.SetCurrentActiveScrolledRoot(
|
||||
savedOutOfFlowData->mContainingBlockActiveScrolledRoot);
|
||||
MOZ_ASSERT(awayFromCommonPath, "It is impossible when savedOutOfFlowData is true");
|
||||
} else if (GetStateBits() & NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO &&
|
||||
isPlaceholder) {
|
||||
NS_ASSERTION(dirty.IsEmpty(), "should have empty dirty rect");
|
||||
|
@ -3053,6 +3127,7 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
|
|||
// instead since we know we won't render anything, and the inner out-of-flow
|
||||
// frame will setup the correct clip for itself.
|
||||
clipState.SetClipChainForContainingBlockDescendants(nullptr);
|
||||
awayFromCommonPath = true;
|
||||
}
|
||||
|
||||
// Setup clipping for the parent's overflow:-moz-hidden-unscrollable,
|
||||
|
@ -3066,7 +3141,9 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
|
|||
nsIFrame* parent = child->GetParent();
|
||||
const nsStyleDisplay* parentDisp =
|
||||
parent == this ? ourDisp : parent->StyleDisplay();
|
||||
ApplyOverflowClipping(aBuilder, parent, parentDisp, clipState);
|
||||
if (ApplyOverflowClipping(aBuilder, parent, parentDisp, clipState)) {
|
||||
awayFromCommonPath = true;
|
||||
}
|
||||
|
||||
nsDisplayList list;
|
||||
nsDisplayList extraPositionedDescendants;
|
||||
|
@ -3089,6 +3166,7 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
|
|||
dirty.IntersectRect(dirty, *clipPropClip);
|
||||
clipState.ClipContentDescendants(
|
||||
*clipPropClip + aBuilder->ToReferenceFrame(child));
|
||||
awayFromCommonPath = true;
|
||||
}
|
||||
|
||||
child->MarkAbsoluteFramesForDisplayList(aBuilder, dirty);
|
||||
|
@ -3114,6 +3192,12 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
|
|||
if (eventRegions) {
|
||||
eventRegions->AddFrame(aBuilder, child);
|
||||
}
|
||||
if (!awayFromCommonPath &&
|
||||
aBuilder->IsPaintingToWindow() &&
|
||||
!buildingForChild.MaybeAnimatedGeometryRoot()) {
|
||||
// The shortcut is available for the child for next time.
|
||||
child->AddStateBits(NS_FRAME_SIMPLE_DISPLAYLIST);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -273,6 +273,10 @@ FRAME_STATE_BIT(Generic, 55, NS_FRAME_OWNS_ANON_BOXES)
|
|||
// Frame has properties in the nsIFrame::Properties() hash.
|
||||
FRAME_STATE_BIT(Generic, 56, NS_FRAME_HAS_PROPERTIES)
|
||||
|
||||
// The display list of the frame can be handled by the shortcut for
|
||||
// COMMON CASE.
|
||||
FRAME_STATE_BIT(Generic, 57, NS_FRAME_SIMPLE_DISPLAYLIST)
|
||||
|
||||
// Set for all descendants of MathML sub/supscript elements (other than the
|
||||
// base frame) to indicate that the SSTY font feature should be used.
|
||||
FRAME_STATE_BIT(Generic, 58, NS_FRAME_MATHML_SCRIPT_DESCENDANT)
|
||||
|
|
|
@ -973,7 +973,7 @@ AnimatedGeometryRoot*
|
|||
nsDisplayListBuilder::WrapAGRForFrame(nsIFrame* aAnimatedGeometryRoot,
|
||||
AnimatedGeometryRoot* aParent /* = nullptr */)
|
||||
{
|
||||
MOZ_ASSERT(IsAnimatedGeometryRoot(aAnimatedGeometryRoot));
|
||||
MOZ_ASSERT(IsAnimatedGeometryRoot(aAnimatedGeometryRoot) == AGR_YES);
|
||||
|
||||
AnimatedGeometryRoot* result = nullptr;
|
||||
if (!mFrameToAnimatedGeometryRootMap.Get(aAnimatedGeometryRoot, &result)) {
|
||||
|
@ -1477,72 +1477,94 @@ IsStickyFrameActive(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, nsIFrame*
|
|||
return sf->IsScrollingActive(aBuilder) && sf->GetScrolledFrame() == cursor;
|
||||
}
|
||||
|
||||
bool
|
||||
nsDisplayListBuilder::IsAnimatedGeometryRoot(nsIFrame* aFrame, nsIFrame** aParent)
|
||||
nsDisplayListBuilder::AGRState
|
||||
nsDisplayListBuilder::IsAnimatedGeometryRoot(nsIFrame* aFrame,
|
||||
nsIFrame** aParent)
|
||||
{
|
||||
if (aFrame == mReferenceFrame) {
|
||||
return true;
|
||||
return AGR_YES;
|
||||
}
|
||||
if (!IsPaintingToWindow()) {
|
||||
if (aParent) {
|
||||
*aParent = nsLayoutUtils::GetCrossDocParentFrame(aFrame);
|
||||
}
|
||||
return false;
|
||||
return AGR_NO;
|
||||
}
|
||||
|
||||
if (nsLayoutUtils::IsPopup(aFrame))
|
||||
return true;
|
||||
return AGR_YES;
|
||||
if (ActiveLayerTracker::IsOffsetOrMarginStyleAnimated(aFrame)) {
|
||||
const bool inBudget = AddToAGRBudget(aFrame);
|
||||
if (inBudget) {
|
||||
return true;
|
||||
return AGR_YES;
|
||||
}
|
||||
}
|
||||
if (!aFrame->GetParent() &&
|
||||
nsLayoutUtils::ViewportHasDisplayPort(aFrame->PresContext())) {
|
||||
// Viewport frames in a display port need to be animated geometry roots
|
||||
// for background-attachment:fixed elements.
|
||||
return true;
|
||||
return AGR_YES;
|
||||
}
|
||||
if (aFrame->IsTransformed()) {
|
||||
return true;
|
||||
return AGR_YES;
|
||||
}
|
||||
|
||||
nsIFrame* parent = nsLayoutUtils::GetCrossDocParentFrame(aFrame);
|
||||
if (!parent)
|
||||
return true;
|
||||
return AGR_YES;
|
||||
|
||||
bool maybe = false; // Possible to transition from not being an AGR
|
||||
// to being an AGR without a style change.
|
||||
|
||||
LayoutFrameType parentType = parent->Type();
|
||||
// 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 &&
|
||||
nsLayoutUtils::IsScrollbarThumbLayerized(aFrame)) {
|
||||
return true;
|
||||
if (parentType == LayoutFrameType::Slider) {
|
||||
if (nsLayoutUtils::IsScrollbarThumbLayerized(aFrame)) {
|
||||
return AGR_YES;
|
||||
}
|
||||
maybe = true;
|
||||
}
|
||||
|
||||
if (aFrame->StyleDisplay()->mPosition == NS_STYLE_POSITION_STICKY &&
|
||||
IsStickyFrameActive(this, aFrame, parent))
|
||||
{
|
||||
return true;
|
||||
if (aFrame->StyleDisplay()->mPosition == NS_STYLE_POSITION_STICKY) {
|
||||
if (IsStickyFrameActive(this, aFrame, parent)) {
|
||||
return AGR_YES;
|
||||
}
|
||||
maybe = true;
|
||||
}
|
||||
|
||||
if (parentType == LayoutFrameType::Scroll ||
|
||||
parentType == LayoutFrameType::ListControl) {
|
||||
nsIScrollableFrame* sf = do_QueryFrame(parent);
|
||||
if (sf->IsScrollingActive(this) && sf->GetScrolledFrame() == aFrame) {
|
||||
return true;
|
||||
if (sf->GetScrolledFrame() == aFrame) {
|
||||
if (sf->IsScrollingActive(this)) {
|
||||
return AGR_YES;
|
||||
}
|
||||
maybe = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Fixed-pos frames are parented by the viewport frame, which has no parent.
|
||||
if (nsLayoutUtils::IsFixedPosFrameInDisplayPort(aFrame)) {
|
||||
return true;
|
||||
return AGR_YES;
|
||||
}
|
||||
|
||||
if ((aFrame->GetStateBits() & NS_FRAME_MAY_BE_TRANSFORMED) &&
|
||||
aFrame->IsFrameOfType(nsIFrame::eSVG)) {
|
||||
// For SVG containers, they always have
|
||||
// NS_FRAME_MAY_BE_TRANSFORMED bit. However, they would be
|
||||
// affected by the fragement identifiers in the svgView form at
|
||||
// runtime without a new style context.
|
||||
// For example, layout/reftests/svg/fragmentIdentifier-01.xhtml
|
||||
//
|
||||
// see https://www.w3.org/TR/SVG/linking.html#SVGFragmentIdentifiers
|
||||
maybe = true;
|
||||
}
|
||||
|
||||
if (aParent) {
|
||||
*aParent = parent;
|
||||
}
|
||||
return false;
|
||||
return !maybe ? AGR_NO : AGR_MAYBE;
|
||||
}
|
||||
|
||||
nsIFrame*
|
||||
|
@ -1552,7 +1574,7 @@ nsDisplayListBuilder::FindAnimatedGeometryRootFrameFor(nsIFrame* aFrame)
|
|||
nsIFrame* cursor = aFrame;
|
||||
while (cursor != RootReferenceFrame()) {
|
||||
nsIFrame* next;
|
||||
if (IsAnimatedGeometryRoot(cursor, &next))
|
||||
if (IsAnimatedGeometryRoot(cursor, &next) == AGR_YES)
|
||||
return cursor;
|
||||
cursor = next;
|
||||
}
|
||||
|
@ -1563,7 +1585,7 @@ void
|
|||
nsDisplayListBuilder::RecomputeCurrentAnimatedGeometryRoot()
|
||||
{
|
||||
if (*mCurrentAGR != mCurrentFrame &&
|
||||
IsAnimatedGeometryRoot(const_cast<nsIFrame*>(mCurrentFrame))) {
|
||||
IsAnimatedGeometryRoot(const_cast<nsIFrame*>(mCurrentFrame)) == AGR_YES) {
|
||||
AnimatedGeometryRoot* oldAGR = mCurrentAGR;
|
||||
mCurrentAGR = WrapAGRForFrame(const_cast<nsIFrame*>(mCurrentFrame), mCurrentAGR);
|
||||
|
||||
|
|
|
@ -283,6 +283,15 @@ class nsDisplayListBuilder {
|
|||
nsRect mDirtyRect;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* AGR_MAYBE means the frame is not an AGR for now, but a transition
|
||||
* to AGR_YES without restyling is possible.
|
||||
*/
|
||||
enum AGRState { AGR_NO, AGR_YES, AGR_MAYBE };
|
||||
|
||||
public:
|
||||
typedef mozilla::FrameLayerBuilder FrameLayerBuilder;
|
||||
typedef mozilla::DisplayItemClip DisplayItemClip;
|
||||
|
@ -818,8 +827,9 @@ public:
|
|||
aBuilder->FindReferenceFrameFor(aForChild,
|
||||
&aBuilder->mCurrentOffsetToReferenceFrame);
|
||||
}
|
||||
mCurrentAGRState = aBuilder->IsAnimatedGeometryRoot(aForChild);
|
||||
if (aBuilder->mCurrentFrame == aForChild->GetParent()) {
|
||||
if (aBuilder->IsAnimatedGeometryRoot(aForChild)) {
|
||||
if (mCurrentAGRState == AGR_YES) {
|
||||
aBuilder->mCurrentAGR = aBuilder->WrapAGRForFrame(aForChild, aBuilder->mCurrentAGR);
|
||||
}
|
||||
} else if (aForChild != aBuilder->mCurrentFrame) {
|
||||
|
@ -843,8 +853,10 @@ public:
|
|||
return mPrevAnimatedGeometryRoot;
|
||||
}
|
||||
bool IsAnimatedGeometryRoot() const {
|
||||
return *mBuilder->mCurrentAGR == mBuilder->mCurrentFrame;
|
||||
|
||||
return mCurrentAGRState == AGR_YES;
|
||||
}
|
||||
bool MaybeAnimatedGeometryRoot() const {
|
||||
return mCurrentAGRState == AGR_MAYBE;
|
||||
}
|
||||
void RestoreBuildingInvisibleItemsValue() {
|
||||
mBuilder->mBuildingInvisibleItems = mPrevBuildingInvisibleItems;
|
||||
|
@ -862,6 +874,7 @@ public:
|
|||
}
|
||||
private:
|
||||
nsDisplayListBuilder* mBuilder;
|
||||
AGRState mCurrentAGRState;
|
||||
const nsIFrame* mPrevFrame;
|
||||
const nsIFrame* mPrevReferenceFrame;
|
||||
nsIFrame* mPrevAnimatedGeometryRoot;
|
||||
|
@ -1398,7 +1411,8 @@ private:
|
|||
* Returns whether a frame acts as an animated geometry root, optionally
|
||||
* returning the next ancestor to check.
|
||||
*/
|
||||
bool IsAnimatedGeometryRoot(nsIFrame* aFrame, nsIFrame** aParent = nullptr);
|
||||
AGRState IsAnimatedGeometryRoot(nsIFrame* aFrame,
|
||||
nsIFrame** aParent = nullptr);
|
||||
|
||||
/**
|
||||
* Returns the nearest ancestor frame to aFrame that is considered to have
|
||||
|
|
Загрузка…
Ссылка в новой задаче