Bug 1390409 part 2 - Replace aParentWasRestyled with a bitflag. r?emilio
MozReview-Commit-ID: 49C1N6LNXi7
--- a/layout/base/ServoRestyleManager.cpp
+++ b/layout/base/ServoRestyleManager.cpp
@@ -640,22 +640,31 @@ UpdateFramePseudoElementStyles(nsIFrame*
if (aFrame->IsFrameOfType(nsIFrame::eBlockFrame)) {
static_cast<nsBlockFrame*>(aFrame)->UpdatePseudoElementStyles(aRestyleState);
}
UpdateBackdropIfNeeded(
aFrame, aRestyleState.StyleSet(), aRestyleState.ChangeList());
}
+enum class ServoPostTraversalFlags : uint32_t
+{
+ Empty = 0,
+ // Whether parent was restyled.
+ ParentWasRestyled = 1 << 0,
+};
+
+MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(ServoPostTraversalFlags)
+
bool
ServoRestyleManager::ProcessPostTraversal(
Element* aElement,
ServoStyleContext* aParentContext,
ServoRestyleState& aRestyleState,
- bool aParentWasRestyled)
+ ServoPostTraversalFlags aFlags)
{
nsIFrame* styleFrame = nsLayoutUtils::GetStyleFrame(aElement);
nsIFrame* primaryFrame = aElement->GetPrimaryFrame();
// NOTE(emilio): This is needed because for table frames the bit is set on the
// table wrapper (which is the primary frame), not on the table itself.
const bool isOutOfFlow =
primaryFrame &&
@@ -689,17 +698,18 @@ ServoRestyleManager::ProcessPostTraversa
} else {
maybeAnonBoxChild = primaryFrame;
changeHint = NS_RemoveSubsumedHints(
changeHint, aRestyleState.ChangesHandledFor(*styleFrame));
}
// If the parent wasn't restyled, the styles of our anon box parents won't
// change either.
- if (aParentWasRestyled && maybeAnonBoxChild->ParentIsWrapperAnonBox()) {
+ if ((aFlags & ServoPostTraversalFlags::ParentWasRestyled) &&
+ maybeAnonBoxChild->ParentIsWrapperAnonBox()) {
aRestyleState.AddPendingWrapperRestyle(
ServoRestyleState::TableAwareParentFor(maybeAnonBoxChild));
}
}
// Although we shouldn't generate non-ReconstructFrame hints for elements with
// no frames, we can still get them here if they were explicitly posted by
// PostRestyleEvent, such as a RepaintFrame hint when a :link changes to be
@@ -812,32 +822,35 @@ ServoRestyleManager::ProcessPostTraversa
styleFrame, aElement, aRestyleState.ChangeList());
}
const bool traverseElementChildren =
aElement->HasAnyOfFlags(Element::kAllServoDescendantBits);
const bool traverseTextChildren =
wasRestyled || aElement->HasFlag(NODE_DESCENDANTS_NEED_FRAMES);
bool recreatedAnyContext = wasRestyled;
+ ServoPostTraversalFlags childrenFlags =
+ wasRestyled ? ServoPostTraversalFlags::ParentWasRestyled
+ : ServoPostTraversalFlags::Empty;
if (traverseElementChildren || traverseTextChildren) {
StyleChildrenIterator it(aElement);
TextPostTraversalState textState(*aElement,
upToDateContext,
displayContentsStyle && wasRestyled,
childrenRestyleState);
for (nsIContent* n = it.GetNextChild(); n; n = it.GetNextChild()) {
if (traverseElementChildren && n->IsElement()) {
recreatedAnyContext |= ProcessPostTraversal(n->AsElement(),
upToDateContext,
childrenRestyleState,
- wasRestyled);
+ childrenFlags);
} else if (traverseTextChildren && n->IsNodeOfType(nsINode::eTEXT)) {
recreatedAnyContext |= ProcessPostTraversalForText(n, textState,
childrenRestyleState,
- wasRestyled);
+ childrenFlags);
}
}
}
// We want to update frame pseudo-element styles after we've traversed our
// kids, because some of those updates (::first-line/::first-letter) need to
// modify the styles of the kids, and the child traversal above would just
// clobber those modifications.
@@ -874,34 +887,35 @@ ServoRestyleManager::ProcessPostTraversa
return recreatedAnyContext;
}
bool
ServoRestyleManager::ProcessPostTraversalForText(
nsIContent* aTextNode,
TextPostTraversalState& aPostTraversalState,
ServoRestyleState& aRestyleState,
- bool aParentWasRestyled)
+ ServoPostTraversalFlags aFlags)
{
// Handle lazy frame construction.
if (aTextNode->HasFlag(NODE_NEEDS_FRAME)) {
aPostTraversalState.ChangeList().AppendChange(
nullptr, aTextNode, nsChangeHint_ReconstructFrame);
return true;
}
// Handle restyle.
nsIFrame* primaryFrame = aTextNode->GetPrimaryFrame();
if (!primaryFrame) {
return false;
}
// If the parent wasn't restyled, the styles of our anon box parents won't
// change either.
- if (aParentWasRestyled && primaryFrame->ParentIsWrapperAnonBox()) {
+ if ((aFlags & ServoPostTraversalFlags::ParentWasRestyled) &&
+ primaryFrame->ParentIsWrapperAnonBox()) {
aRestyleState.AddPendingWrapperRestyle(
ServoRestyleState::TableAwareParentFor(primaryFrame));
}
nsStyleContext& newContext = aPostTraversalState.ComputeStyle(aTextNode);
aPostTraversalState.ComputeHintIfNeeded(aTextNode, primaryFrame, newContext);
// We want to walk all the continuations here, even the ones with different
@@ -1019,19 +1033,18 @@ ServoRestyleManager::DoProcessPendingRes
// Recreate style contexts, and queue up change hints (which also handle
// lazy frame construction).
{
AutoRestyleTimelineMarker marker(mPresContext->GetDocShell(), false);
DocumentStyleRootIterator iter(doc->GetServoRestyleRoot());
while (Element* root = iter.GetNextStyleRoot()) {
nsTArray<nsIFrame*> wrappersToRestyle;
ServoRestyleState state(*styleSet, currentChanges, wrappersToRestyle);
- anyStyleChanged |=
- ProcessPostTraversal(root, nullptr, state,
- /* aParentWasRestyled = */ false);
+ ServoPostTraversalFlags flags = ServoPostTraversalFlags::Empty;
+ anyStyleChanged |= ProcessPostTraversal(root, nullptr, state, flags);
}
}
doc->ClearServoRestyleRoot();
// Process the change hints.
//
// Unfortunately, the frame constructor can generate new change hints while
--- a/layout/base/ServoRestyleManager.h
+++ b/layout/base/ServoRestyleManager.h
@@ -158,16 +158,18 @@ private:
// Whether we should assert in our destructor that we've processed all of the
// relevant wrapper restyles.
#ifdef DEBUG
const bool mAssertWrapperRestyleLength = true;
#endif // DEBUG
};
+enum class ServoPostTraversalFlags : uint32_t;
+
/**
* Restyle manager for a Servo-backed style system.
*/
class ServoRestyleManager : public RestyleManager
{
friend class ServoStyleSet;
public:
@@ -256,23 +258,23 @@ private:
* Returns whether any style did actually change. There may be cases where we
* didn't need to change any style after all, for example, when a content
* attribute changes that happens not to have any effect on the style of that
* element or any descendant or sibling.
*/
bool ProcessPostTraversal(Element* aElement,
ServoStyleContext* aParentContext,
ServoRestyleState& aRestyleState,
- bool aParentWasRestyled);
+ ServoPostTraversalFlags aFlags);
struct TextPostTraversalState;
bool ProcessPostTraversalForText(nsIContent* aTextNode,
TextPostTraversalState& aState,
ServoRestyleState& aRestyleState,
- bool aParentWasRestyled);
+ ServoPostTraversalFlags aFlags);
inline ServoStyleSet* StyleSet() const
{
MOZ_ASSERT(PresContext()->StyleSet()->IsServo(),
"ServoRestyleManager should only be used with a Servo-flavored "
"style backend");
return PresContext()->StyleSet()->AsServo();
}