Bug 1356103 - Part 3: Make it easy to access the ServoStyleSet currently in traversal. r=bholley
In a later patch, we'll want to queue up some tasks to run when the
Servo traversal is one, and the ServoStyleSet seems like the natural
place to store those tasks. We could probably find the ServoStyleSet
by chasing a bunch of pointers from the task-adding call sites, but
it seems simpler just to make it available directly.
MozReview-Commit-ID: AJoFZEoNaGm
--- a/layout/style/ServoStyleSet.cpp
+++ b/layout/style/ServoStyleSet.cpp
@@ -290,18 +290,17 @@ ServoStyleSet::PrepareAndTraverseSubtree
TraversalRestyleBehavior
aRestyleBehavior)
{
// Get the Document's root element to ensure that the cache is valid before
// calling into the (potentially-parallel) Servo traversal, where a cache hit
// is necessary to avoid a data race when updating the cache.
mozilla::Unused << aRoot->OwnerDoc()->GetRootElement();
- MOZ_ASSERT(!sInServoTraversal);
- sInServoTraversal = true;
+ AutoSetInServoTraversal guard(this);
bool isInitial = !aRoot->HasServoData();
bool forReconstruct =
aRestyleBehavior == TraversalRestyleBehavior::ForReconstruct;
bool postTraversalRequired =
Servo_TraverseSubtree(aRoot, mRawSet.get(), aRootBehavior, aRestyleBehavior);
MOZ_ASSERT_IF(isInitial || forReconstruct, !postTraversalRequired);
@@ -333,17 +332,16 @@ ServoStyleSet::PrepareAndTraverseSubtree
MOZ_ASSERT(!postTraversalRequired);
ServoRestyleManager::ClearRestyleStateFromSubtree(root);
} else {
postTraversalRequired = true;
}
}
}
- sInServoTraversal = false;
return postTraversalRequired;
}
already_AddRefed<nsStyleContext>
ServoStyleSet::ResolveStyleFor(Element* aElement,
nsStyleContext* aParentContext,
LazyComputeBehavior aMayCompute,
TreeMatchContext& aTreeMatchContext)
@@ -978,18 +976,18 @@ ServoStyleSet::ClearNonInheritingStyleCo
ptr = nullptr;
}
}
already_AddRefed<ServoComputedValues>
ServoStyleSet::ResolveStyleLazily(Element* aElement, nsIAtom* aPseudoTag)
{
mPresContext->EffectCompositor()->PreTraverse(aElement, aPseudoTag);
- MOZ_ASSERT(!sInServoTraversal);
- sInServoTraversal = true;
+
+ AutoSetInServoTraversal guard(this);
/**
* NB: This is needed because we process animations and transitions on the
* pseudo-elements themselves, not on the parent's EagerPseudoStyles.
*
* That means that that style doesn't account for animations, and we can't do
* that easily from the traversal without doing wasted work.
*
@@ -1018,18 +1016,16 @@ ServoStyleSet::ResolveStyleLazily(Elemen
if (mPresContext->EffectCompositor()->PreTraverse(aElement, aPseudoTag)) {
computedValues =
Servo_ResolveStyleLazily(elementForStyleResolution,
pseudoTagForStyleResolution,
mRawSet.get()).Consume();
}
- sInServoTraversal = false;
-
return computedValues.forget();
}
bool
ServoStyleSet::AppendFontFaceRules(nsTArray<nsFontFaceRuleContainer>& aArray)
{
Servo_StyleSet_GetFontFaceRules(mRawSet.get(), &aArray);
return true;
@@ -1105,9 +1101,9 @@ ServoStyleSet::RemoveSheetOfType(SheetTy
uint32_t uniqueID = mEntries[aType][i].uniqueID;
mEntries[aType].RemoveElementAt(i);
return uniqueID;
}
}
return 0;
}
-bool ServoStyleSet::sInServoTraversal = false;
+ServoStyleSet* ServoStyleSet::sInServoTraversal = nullptr;
--- a/layout/style/ServoStyleSet.h
+++ b/layout/style/ServoStyleSet.h
@@ -80,16 +80,21 @@ public:
// maintain this static boolean. However, the danger is that those callers
// are generally unprepared to deal with non-Servo-but-also-non-main-thread
// callers, and are likely to take the main-thread codepath if this function
// returns false. So we assert against other non-main-thread callers here.
MOZ_ASSERT(sInServoTraversal || NS_IsMainThread());
return sInServoTraversal;
}
+ static ServoStyleSet* Current()
+ {
+ return sInServoTraversal;
+ }
+
ServoStyleSet();
~ServoStyleSet();
void Init(nsPresContext* aPresContext);
void BeginShutdown();
void Shutdown();
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
@@ -304,16 +309,33 @@ public:
ResolveForDeclarations(ServoComputedValuesBorrowedOrNull aParentOrNull,
RawServoDeclarationBlockBorrowed aDeclarations);
already_AddRefed<RawServoAnimationValue>
ComputeAnimationValue(RawServoDeclarationBlock* aDeclaration,
const ServoComputedValuesWithParent& aComputedValues);
private:
+ class MOZ_STACK_CLASS AutoSetInServoTraversal
+ {
+ public:
+ explicit AutoSetInServoTraversal(ServoStyleSet* aSet)
+ {
+ MOZ_ASSERT(!sInServoTraversal);
+ MOZ_ASSERT(aSet);
+ sInServoTraversal = aSet;
+ }
+
+ ~AutoSetInServoTraversal()
+ {
+ MOZ_ASSERT(sInServoTraversal);
+ sInServoTraversal = nullptr;
+ }
+ };
+
already_AddRefed<nsStyleContext> GetContext(already_AddRefed<ServoComputedValues>,
nsStyleContext* aParentContext,
nsIAtom* aPseudoTag,
CSSPseudoElementType aPseudoType,
dom::Element* aElementForAnimation);
already_AddRefed<nsStyleContext> GetContext(nsIContent* aContent,
nsStyleContext* aParentContext,
@@ -394,14 +416,14 @@ private:
bool mAuthorStyleDisabled;
// Stores pointers to our cached style contexts for non-inheriting anonymous
// boxes.
EnumeratedArray<nsCSSAnonBoxes::NonInheriting,
nsCSSAnonBoxes::NonInheriting::_Count,
RefPtr<nsStyleContext>> mNonInheritingStyleContexts;
- static bool sInServoTraversal;
+ static ServoStyleSet* sInServoTraversal;
};
} // namespace mozilla
#endif // mozilla_ServoStyleSet_h