Bug 1384769 - Pass TraversalFlags from C++ into Rust. r=emilio

MozReview-Commit-ID: EVUzgnL5coN
This commit is contained in:
Bobby Holley 2017-07-25 18:45:37 -07:00
Родитель 68cdedacfc
Коммит 12955e0dde
8 изменённых файлов: 74 добавлений и 107 удалений

Просмотреть файл

@ -254,7 +254,7 @@ ServoRestyleManager::ClearRestyleStateFromSubtree(Element* aElement)
bool wasRestyled;
Unused << Servo_TakeChangeHint(aElement,
TraversalRestyleBehavior::Normal,
ServoTraversalFlags::Empty,
&wasRestyled);
aElement->UnsetHasDirtyDescendantsForServo();
aElement->UnsetHasAnimationOnlyDirtyDescendantsForServo();
@ -492,13 +492,13 @@ UpdateFramePseudoElementStyles(nsIFrame* aFrame,
static inline bool
NeedsToTraverseElementChildren(const Element& aParent,
TraversalRestyleBehavior aRestyleBehavior)
ServoTraversalFlags aFlags)
{
if (aParent.HasAnimationOnlyDirtyDescendantsForServo()) {
return true;
}
if (aRestyleBehavior != TraversalRestyleBehavior::ForThrottledAnimationFlush) {
if (!(aFlags & ServoTraversalFlags::ForThrottledAnimationFlush)) {
return aParent.HasDirtyDescendantsForServo() ||
aParent.HasFlag(NODE_DESCENDANTS_NEED_FRAMES);
}
@ -510,7 +510,7 @@ ServoRestyleManager::ProcessPostTraversal(
Element* aElement,
ServoStyleContext* aParentContext,
ServoRestyleState& aRestyleState,
TraversalRestyleBehavior aRestyleBehavior)
ServoTraversalFlags aFlags)
{
nsIFrame* styleFrame = nsLayoutUtils::GetStyleFrame(aElement);
@ -526,7 +526,7 @@ ServoRestyleManager::ProcessPostTraversal(
// in normal restyle later.
bool wasRestyled;
nsChangeHint changeHint = Servo_TakeChangeHint(aElement,
aRestyleBehavior,
aFlags,
&wasRestyled);
// We should really fix the weird primary frame mapping for image maps
@ -604,7 +604,7 @@ ServoRestyleManager::ProcessPostTraversal(
if (wasRestyled && oldStyleContext) {
MOZ_ASSERT(styleFrame || displayContentsNode);
newContext =
aRestyleState.StyleSet().ResolveServoStyle(aElement, aRestyleBehavior);
aRestyleState.StyleSet().ResolveServoStyle(aElement, aFlags);
MOZ_ASSERT(oldStyleContext->ComputedData() != newContext->ComputedData());
newContext->ResolveSameStructsAs(oldStyleContext);
@ -658,11 +658,11 @@ ServoRestyleManager::ProcessPostTraversal(
}
const bool traverseElementChildren =
NeedsToTraverseElementChildren(*aElement, aRestyleBehavior);
NeedsToTraverseElementChildren(*aElement, aFlags);
const bool descendantsNeedFrames =
aElement->HasFlag(NODE_DESCENDANTS_NEED_FRAMES);
const bool forThrottledAnimationFlush =
aRestyleBehavior == TraversalRestyleBehavior::ForThrottledAnimationFlush;
!!(aFlags & ServoTraversalFlags::ForThrottledAnimationFlush);
const bool traverseTextChildren =
wasRestyled || (!forThrottledAnimationFlush && descendantsNeedFrames);
bool recreatedAnyContext = wasRestyled;
@ -679,7 +679,7 @@ ServoRestyleManager::ProcessPostTraversal(
recreatedAnyContext |= ProcessPostTraversal(n->AsElement(),
upToDateContext,
childrenRestyleState,
aRestyleBehavior);
aFlags);
} else if (traverseTextChildren && n->IsNodeOfType(nsINode::eTEXT)) {
recreatedAnyContext |= ProcessPostTraversalForText(n, textState);
}
@ -810,8 +810,7 @@ ServoRestyleManager::FrameForPseudoElement(const Element* aElement,
}
void
ServoRestyleManager::DoProcessPendingRestyles(TraversalRestyleBehavior
aRestyleBehavior)
ServoRestyleManager::DoProcessPendingRestyles(ServoTraversalFlags aFlags)
{
MOZ_ASSERT(PresContext()->Document(), "No document? Pshaw!");
MOZ_ASSERT(!nsContentUtils::IsSafeToRunScript(), "Missing a script blocker!");
@ -834,7 +833,7 @@ ServoRestyleManager::DoProcessPendingRestyles(TraversalRestyleBehavior
ServoStyleSet* styleSet = StyleSet();
nsIDocument* doc = PresContext()->Document();
bool forThrottledAnimationFlush =
aRestyleBehavior == TraversalRestyleBehavior::ForThrottledAnimationFlush;
!!(aFlags & ServoTraversalFlags::ForThrottledAnimationFlush);
// Ensure the refresh driver is active during traversal to avoid mutating
// mActiveTimer and mMostRecentRefresh time.
@ -849,12 +848,13 @@ ServoRestyleManager::DoProcessPendingRestyles(TraversalRestyleBehavior
++mAnimationGeneration;
}
TraversalRestyleBehavior restyleBehavior = mRestyleForCSSRuleChanges
? TraversalRestyleBehavior::ForCSSRuleChanges
: TraversalRestyleBehavior::Normal;
if (mRestyleForCSSRuleChanges) {
aFlags |= ServoTraversalFlags::ForCSSRuleChanges;
}
while (forThrottledAnimationFlush
? styleSet->StyleDocumentForThrottledAnimationFlush()
: styleSet->StyleDocument(restyleBehavior)) {
: styleSet->StyleDocument(aFlags)) {
if (!forThrottledAnimationFlush) {
ClearSnapshots();
}
@ -871,7 +871,7 @@ ServoRestyleManager::DoProcessPendingRestyles(TraversalRestyleBehavior
while (Element* root = iter.GetNextStyleRoot()) {
ServoRestyleState state(*styleSet, currentChanges);
anyStyleChanged |=
ProcessPostTraversal(root, nullptr, state, aRestyleBehavior);
ProcessPostTraversal(root, nullptr, state, aFlags);
}
}
@ -941,7 +941,7 @@ ServoRestyleManager::DoProcessPendingRestyles(TraversalRestyleBehavior
void
ServoRestyleManager::ProcessPendingRestyles()
{
DoProcessPendingRestyles(TraversalRestyleBehavior::Normal);
DoProcessPendingRestyles(ServoTraversalFlags::Empty);
}
void
@ -953,7 +953,7 @@ ServoRestyleManager::UpdateOnlyAnimationStyles()
return;
}
DoProcessPendingRestyles(TraversalRestyleBehavior::ForThrottledAnimationFlush);
DoProcessPendingRestyles(ServoTraversalFlags::ForThrottledAnimationFlush);
}
void

Просмотреть файл

@ -191,7 +191,7 @@ private:
bool ProcessPostTraversal(Element* aElement,
ServoStyleContext* aParentContext,
ServoRestyleState& aRestyleState,
TraversalRestyleBehavior aRestyleBehavior);
ServoTraversalFlags aFlags);
struct TextPostTraversalState;
bool ProcessPostTraversalForText(nsIContent* aTextNode,
@ -212,7 +212,7 @@ private:
int32_t aNameSpaceID,
nsIAtom* aAttribute);
void DoProcessPendingRestyles(TraversalRestyleBehavior aRestyleBehavior);
void DoProcessPendingRestyles(ServoTraversalFlags aFlags);
// We use a separate data structure from nsStyleChangeList because we need a
// frame to create nsStyleChangeList entries, and the primary frame may not be

Просмотреть файл

@ -2522,7 +2522,7 @@ nsCSSFrameConstructor::ConstructDocElementFrame(Element* aDocEle
// NOTE(emilio): If the root has a non-null binding, we'll stop at the
// document element and won't process any children, loading the bindings (or
// failing to do so) will take care of the rest.
set->StyleDocument(TraversalRestyleBehavior::Normal);
set->StyleDocument(ServoTraversalFlags::Empty);
}
// FIXME: Should this use ResolveStyleContext? (The calls in this

Просмотреть файл

@ -502,12 +502,12 @@ SERVO_BINDING_FUNC(Servo_NoteExplicitHints, void, RawGeckoElementBorrowed elemen
SERVO_BINDING_FUNC(Servo_TakeChangeHint,
nsChangeHint,
RawGeckoElementBorrowed element,
mozilla::TraversalRestyleBehavior restyle_behavior,
mozilla::ServoTraversalFlags flags,
bool* was_restyled)
SERVO_BINDING_FUNC(Servo_ResolveStyle, ServoStyleContextStrong,
RawGeckoElementBorrowed element,
RawServoStyleSetBorrowed set,
mozilla::TraversalRestyleBehavior restyle_behavior)
mozilla::ServoTraversalFlags flags)
SERVO_BINDING_FUNC(Servo_ResolvePseudoStyle, ServoStyleContextStrong,
RawGeckoElementBorrowed element,
mozilla::CSSPseudoElementType pseudo_type,
@ -544,8 +544,7 @@ SERVO_BINDING_FUNC(Servo_TraverseSubtree,
RawGeckoElementBorrowed root,
RawServoStyleSetBorrowed set,
const mozilla::ServoElementSnapshotTable* snapshots,
mozilla::TraversalRootBehavior root_behavior,
mozilla::TraversalRestyleBehavior restyle_behavior)
mozilla::ServoTraversalFlags flags)
// Assert that the tree has no pending or unconsumed restyles.
SERVO_BINDING_FUNC(Servo_AssertTreeIsClean, void, RawGeckoElementBorrowed root)

Просмотреть файл

@ -93,6 +93,7 @@ constified-enums = [
"UpdateAnimationsTasks",
"ParsingMode",
"ThemeWidgetType",
"ServoTraversalFlags",
]
constified-enum-variants = [
{ enum = "nsCSSPropertyID", variants = ["eCSSProperty_COUNT.*"] },
@ -132,8 +133,7 @@ whitelist-types = [
"mozilla::dom::StyleChildrenIterator",
"mozilla::HalfCorner",
"mozilla::PropertyStyleAnimationValuePair",
"mozilla::TraversalRestyleBehavior",
"mozilla::TraversalRootBehavior",
"mozilla::ServoTraversalFlags",
"mozilla::StyleShapeRadius",
"mozilla::StyleGrid.*",
"mozilla::UpdateAnimationsTasks",
@ -386,8 +386,7 @@ structs-types = [
"RefPtr",
"CSSPseudoClassType",
"CSSPseudoElementType",
"TraversalRestyleBehavior",
"TraversalRootBehavior",
"ServoTraversalFlags",
"ComputedTimingFunction_BeforeFlag",
"CounterStylePtr",
"FontFamilyList",

Просмотреть файл

@ -182,7 +182,7 @@ ServoStyleSet::ResolveStyleFor(Element* aElement,
aElement, CSSPseudoElementType::NotPseudo, nullptr, aParentContext);
}
return ResolveServoStyle(aElement, TraversalRestyleBehavior::Normal);
return ResolveServoStyle(aElement, ServoTraversalFlags::Empty);
}
@ -270,11 +270,10 @@ ServoStyleSet::PreTraverse(Element* aRoot,
bool
ServoStyleSet::PrepareAndTraverseSubtree(
RawGeckoElementBorrowed aRoot,
TraversalRootBehavior aRootBehavior,
TraversalRestyleBehavior aRestyleBehavior)
ServoTraversalFlags aFlags)
{
bool forThrottledAnimationFlush =
aRestyleBehavior == TraversalRestyleBehavior::ForThrottledAnimationFlush;
!!(aFlags & ServoTraversalFlags::ForThrottledAnimationFlush);
AutoRestyleTimelineMarker marker(
mPresContext->GetDocShell(), forThrottledAnimationFlush);
@ -290,14 +289,12 @@ ServoStyleSet::PrepareAndTraverseSubtree(
const SnapshotTable& snapshots = Snapshots();
bool isInitial = !aRoot->HasServoData();
bool forReconstruct =
aRestyleBehavior == TraversalRestyleBehavior::ForReconstruct;
bool forReconstruct = !!(aFlags & ServoTraversalFlags::ForReconstruct);
#ifdef DEBUG
bool forNewlyBoundElement =
aRestyleBehavior == TraversalRestyleBehavior::ForNewlyBoundElement;
bool forNewlyBoundElement = !!(aFlags & ServoTraversalFlags::ForNewlyBoundElement);
#endif
bool postTraversalRequired = Servo_TraverseSubtree(
aRoot, mRawSet.get(), &snapshots, aRootBehavior, aRestyleBehavior);
bool postTraversalRequired =
Servo_TraverseSubtree(aRoot, mRawSet.get(), &snapshots, aFlags);
MOZ_ASSERT(!(isInitial || forReconstruct || forNewlyBoundElement) ||
!postTraversalRequired);
@ -324,8 +321,7 @@ ServoStyleSet::PrepareAndTraverseSubtree(
EffectCompositor::AnimationRestyleType::Throttled;
if (forReconstruct ? compositor->PreTraverseInSubtree(root, restyleType)
: compositor->PreTraverse(restyleType)) {
if (Servo_TraverseSubtree(
aRoot, mRawSet.get(), &snapshots, aRootBehavior, aRestyleBehavior)) {
if (Servo_TraverseSubtree(aRoot, mRawSet.get(), &snapshots, aFlags)) {
MOZ_ASSERT(!forReconstruct);
if (isInitial) {
// We're doing initial styling, and the additional animation
@ -420,7 +416,7 @@ ServoStyleSet::ResolvePseudoElementStyle(Element* aOriginatingElement,
computedValues =
Servo_ResolveStyle(aPseudoElement,
mRawSet.get(),
TraversalRestyleBehavior::Normal).Consume();
ServoTraversalFlags::Empty).Consume();
} else {
computedValues =
Servo_ResolvePseudoStyle(aOriginatingElement,
@ -782,13 +778,11 @@ ServoStyleSet::HasStateDependentStyle(dom::Element* aElement,
}
bool
ServoStyleSet::StyleDocument(TraversalRestyleBehavior aRestyleBehavior)
ServoStyleSet::StyleDocument(ServoTraversalFlags aFlags)
{
MOZ_ASSERT(
aRestyleBehavior == TraversalRestyleBehavior::Normal ||
aRestyleBehavior == TraversalRestyleBehavior::ForCSSRuleChanges,
"StyleDocument() should be only called for normal traversal or CSS rule "
"changes");
MOZ_ASSERT(aFlags == ServoTraversalFlags::Empty ||
aFlags == ServoTraversalFlags::ForCSSRuleChanges,
"Should only be called for normal traversal or CSS rule changes");
PreTraverse();
@ -797,9 +791,7 @@ ServoStyleSet::StyleDocument(TraversalRestyleBehavior aRestyleBehavior)
bool postTraversalRequired = false;
DocumentStyleRootIterator iter(mPresContext->Document());
while (Element* root = iter.GetNextStyleRoot()) {
if (PrepareAndTraverseSubtree(root,
TraversalRootBehavior::Normal,
aRestyleBehavior)) {
if (PrepareAndTraverseSubtree(root, aFlags)) {
postTraversalRequired = true;
}
}
@ -814,10 +806,7 @@ ServoStyleSet::StyleDocumentForThrottledAnimationFlush()
bool postTraversalRequired = false;
DocumentStyleRootIterator iter(mPresContext->Document());
while (Element* root = iter.GetNextStyleRoot()) {
if (PrepareAndTraverseSubtree(
root,
TraversalRootBehavior::Normal,
TraversalRestyleBehavior::ForThrottledAnimationFlush)) {
if (PrepareAndTraverseSubtree(root, ServoTraversalFlags::ForThrottledAnimationFlush)) {
postTraversalRequired = true;
}
}
@ -832,9 +821,7 @@ ServoStyleSet::StyleNewSubtree(Element* aRoot)
PreTraverse();
DebugOnly<bool> postTraversalRequired =
PrepareAndTraverseSubtree(aRoot,
TraversalRootBehavior::Normal,
TraversalRestyleBehavior::Normal);
PrepareAndTraverseSubtree(aRoot, ServoTraversalFlags::Empty);
MOZ_ASSERT(!postTraversalRequired);
}
@ -843,9 +830,7 @@ ServoStyleSet::StyleNewChildren(Element* aParent)
{
PreTraverse();
PrepareAndTraverseSubtree(aParent,
TraversalRootBehavior::UnstyledChildrenOnly,
TraversalRestyleBehavior::Normal);
PrepareAndTraverseSubtree(aParent, ServoTraversalFlags::UnstyledChildrenOnly);
// We can't assert that Servo_TraverseSubtree returns false, since aParent
// or some of its other children might have pending restyles.
}
@ -868,14 +853,12 @@ ServoStyleSet::StyleNewlyBoundElement(Element* aElement)
// skip restyling, rather than panic when trying to unwrap the styles
// it expects to have just computed.
TraversalRootBehavior rootBehavior =
MOZ_UNLIKELY(!aElement->HasServoData())
? TraversalRootBehavior::Normal
: TraversalRootBehavior::UnstyledChildrenOnly;
ServoTraversalFlags flags = ServoTraversalFlags::ForNewlyBoundElement |
(MOZ_UNLIKELY(!aElement->HasServoData())
? ServoTraversalFlags::Empty
: ServoTraversalFlags::UnstyledChildrenOnly);
PrepareAndTraverseSubtree(aElement,
rootBehavior,
TraversalRestyleBehavior::ForNewlyBoundElement);
PrepareAndTraverseSubtree(aElement, flags);
}
void
@ -884,9 +867,7 @@ ServoStyleSet::StyleSubtreeForReconstruct(Element* aRoot)
PreTraverse(aRoot);
DebugOnly<bool> postTraversalRequired =
PrepareAndTraverseSubtree(aRoot,
TraversalRootBehavior::Normal,
TraversalRestyleBehavior::ForReconstruct);
PrepareAndTraverseSubtree(aRoot, ServoTraversalFlags::ForReconstruct);
MOZ_ASSERT(!postTraversalRequired);
}
@ -1085,14 +1066,13 @@ UpdateBodyTextColorIfNeeded(
}
already_AddRefed<ServoStyleContext>
ServoStyleSet::ResolveServoStyle(Element* aElement,
TraversalRestyleBehavior aRestyleBehavior)
ServoStyleSet::ResolveServoStyle(Element* aElement, ServoTraversalFlags aFlags)
{
UpdateStylistIfNeeded();
RefPtr<ServoStyleContext> result =
Servo_ResolveStyle(aElement,
mRawSet.get(),
aRestyleBehavior).Consume();
aFlags).Consume();
UpdateBodyTextColorIfNeeded(*aElement, *result, *mPresContext);
return result.forget();
}

Просмотреть файл

@ -264,14 +264,14 @@ public:
* This will traverse all of the document's style roots (that is, its document
* element, and the roots of the document-level native anonymous content).
*
* |aRestyleBehavior| should be `Normal` or `ForCSSRuleChanges`.
* The only allowed flag (for now ) is `ForCSSRuleChanges`.
* We need to specify |ForCSSRuleChanges| to try to update all CSS animations
* when we call this function due to CSS rule changes since @keyframes rules
* may have changed.
*
* Returns true if a post-traversal is required.
*/
bool StyleDocument(TraversalRestyleBehavior aRestyleBehavior);
bool StyleDocument(ServoTraversalFlags aFlags);
/**
* Performs a Servo animation-only traversal to compute style for all nodes
@ -364,8 +364,7 @@ public:
* FIXME(emilio): Is there a point in this after bug 1367904?
*/
already_AddRefed<ServoStyleContext>
ResolveServoStyle(dom::Element* aElement,
TraversalRestyleBehavior aRestyleBehavior);
ResolveServoStyle(dom::Element* aElement, ServoTraversalFlags aFlags);
bool GetKeyframesForName(const nsString& aName,
const nsTimingFunction& aTimingFunction,
@ -507,8 +506,7 @@ private:
* Returns whether a post-traversal is required.
*/
bool PrepareAndTraverseSubtree(RawGeckoElementBorrowed aRoot,
TraversalRootBehavior aRootBehavior,
TraversalRestyleBehavior aRestyleBehavior);
ServoTraversalFlags aFlags);
/**
* Clear our cached mNonInheritingStyleContexts.

Просмотреть файл

@ -49,42 +49,33 @@ enum class LazyComputeBehavior {
Assert,
};
// Indicates whether the Servo style system should perform normal processing or
// whether it should only process unstyled children of the root and their
// descendants.
enum class TraversalRootBehavior {
Normal,
UnstyledChildrenOnly,
};
// Indicates whether the Servo style system should perform normal processing,
// animation-only processing (so we can flush any throttled animation styles),
// or whether it should traverse in a mode that doesn't generate any change
// hints, which is what's required when handling frame reconstruction.
// The change hints in this case are unneeded, since the old frames have
// already been destroyed.
// Indicates how the Servo style system should perform.
enum class TraversalRestyleBehavior {
// Normal processing.
Normal,
// Normal processing, but tolerant to calls to restyle elements in unstyled
// or display:none subtrees (which can occur when styling elements with
// newly applied XBL bindings).
ForNewlyBoundElement,
// Various flags for the servo traversal.
enum class ServoTraversalFlags : uint32_t {
Empty = 0,
// Perform animation processing but not regular styling.
AnimationOnly = 1 << 0,
// Traverses as normal mode but tries to update all CSS animations.
ForCSSRuleChanges = 1 << 1,
// Traverse only unstyled children of the root (and their descendants).
UnstyledChildrenOnly = 1 << 2,
// Traverses in a mode that doesn't generate any change hints, which is what's
// required when handling frame reconstruction. The change hints in this case
// are unneeded, since the old frames have already been destroyed.
ForReconstruct,
ForReconstruct = 1 << 3,
// Be tolerant to calls to restyle elements in unstyled
// or display:none subtrees (which can occur when styling elements with
// newly applied XBL bindings).
ForNewlyBoundElement = 1 << 4,
// Processes just the traversal for animation-only restyles and skips the
// normal traversal for other restyles unrelated to animations.
// This is used to bring throttled animations up-to-date such as when we need
// to get correct position for transform animations that are throttled because
// they are running on the compositor.
ForThrottledAnimationFlush,
// Traverses as normal mode but tries to update all CSS animations.
ForCSSRuleChanges,
ForThrottledAnimationFlush = 1 << 5,
};
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(ServoTraversalFlags)
// Indicates which rules should be included when performing selecting matching
// on an element. DefaultOnly is used to exclude all rules except for those
// that come from UA style sheets, and is used to implemented