Bug 1351535 - Part 4: Add a TraversalRestyleBehavior argument to traversal functions. r=bholley
This argument will be used to control whether we are restyling in preparation
for reframing a subtree, which can avoid generating any change hints, as we
aren't preserving the frames that they would otherwise apply to.
MozReview-Commit-ID: DkLVCUnNGt
--- a/layout/style/ServoBindingList.h
+++ b/layout/style/ServoBindingList.h
@@ -319,17 +319,18 @@ SERVO_BINDING_FUNC(Servo_ResolvePseudoSt
SERVO_BINDING_FUNC(Servo_ResolveStyleLazily, ServoComputedValuesStrong,
RawGeckoElementBorrowed element, nsIAtom* pseudo_tag,
RawServoStyleSetBorrowed set)
// Use ServoStyleSet::PrepareAndTraverseSubtree instead of calling this
// directly
SERVO_BINDING_FUNC(Servo_TraverseSubtree, bool,
RawGeckoElementBorrowed root, RawServoStyleSetBorrowed set,
- mozilla::TraversalRootBehavior root_behavior)
+ mozilla::TraversalRootBehavior root_behavior,
+ mozilla::TraversalRestyleBehavior restyle_behavior)
// Assert that the tree has no pending or unconsumed restyles.
SERVO_BINDING_FUNC(Servo_AssertTreeIsClean, void, RawGeckoElementBorrowed root)
// Returns computed values for the given element without any animations rules.
SERVO_BINDING_FUNC(Servo_StyleSet_GetBaseComputedValuesForElement,
ServoComputedValuesStrong,
RawServoStyleSetBorrowed set,
--- a/layout/style/ServoStyleSet.cpp
+++ b/layout/style/ServoStyleSet.cpp
@@ -220,35 +220,38 @@ ServoStyleSet::PreTraverse()
// Process animation stuff that we should avoid doing during the parallel
// traversal.
mPresContext->EffectCompositor()->PreTraverse();
}
bool
ServoStyleSet::PrepareAndTraverseSubtree(RawGeckoElementBorrowed aRoot,
- mozilla::TraversalRootBehavior aRootBehavior)
+ TraversalRootBehavior aRootBehavior,
+ 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;
bool isInitial = !aRoot->HasServoData();
bool postTraversalRequired =
- Servo_TraverseSubtree(aRoot, mRawSet.get(), aRootBehavior);
+ Servo_TraverseSubtree(aRoot, mRawSet.get(), aRootBehavior, aRestyleBehavior);
MOZ_ASSERT_IF(isInitial, !postTraversalRequired);
// If there are still animation restyles needed, trigger a second traversal to
// update CSS animations' styles.
if (mPresContext->EffectCompositor()->PreTraverse()) {
- if (Servo_TraverseSubtree(aRoot, mRawSet.get(), aRootBehavior)) {
+ if (Servo_TraverseSubtree(aRoot, mRawSet.get(),
+ aRootBehavior, aRestyleBehavior)) {
if (isInitial) {
// We're doing initial styling, and the additional animation
// traversal changed the styles that were set by the first traversal.
// This would normally require a post-traversal to update the style
// contexts, and the DOM now has dirty descendant bits and RestyleData
// in expectation of that post-traversal. But since this is actually
// the initial styling, there are no style contexts to update and no
// frames to apply the change hints to, so we don't need to do that
@@ -703,41 +706,47 @@ ServoStyleSet::StyleDocument()
{
PreTraverse();
// Restyle the document from the root element and each of the document level
// NAC subtree roots.
bool postTraversalRequired = false;
DocumentStyleRootIterator iter(mPresContext->Document());
while (Element* root = iter.GetNextStyleRoot()) {
- if (PrepareAndTraverseSubtree(root, TraversalRootBehavior::Normal)) {
+ if (PrepareAndTraverseSubtree(root,
+ TraversalRootBehavior::Normal,
+ TraversalRestyleBehavior::Normal)) {
postTraversalRequired = true;
}
}
return postTraversalRequired;
}
void
ServoStyleSet::StyleNewSubtree(Element* aRoot)
{
MOZ_ASSERT(!aRoot->HasServoData());
PreTraverse();
DebugOnly<bool> postTraversalRequired =
- PrepareAndTraverseSubtree(aRoot, TraversalRootBehavior::Normal);
+ PrepareAndTraverseSubtree(aRoot,
+ TraversalRootBehavior::Normal,
+ TraversalRestyleBehavior::Normal);
MOZ_ASSERT(!postTraversalRequired);
}
void
ServoStyleSet::StyleNewChildren(Element* aParent)
{
PreTraverse();
- PrepareAndTraverseSubtree(aParent, TraversalRootBehavior::UnstyledChildrenOnly);
+ PrepareAndTraverseSubtree(aParent,
+ TraversalRootBehavior::UnstyledChildrenOnly,
+ TraversalRestyleBehavior::Normal);
// We can't assert that Servo_TraverseSubtree returns false, since aParent
// or some of its other children might have pending restyles.
}
void
ServoStyleSet::NoteStyleSheetsChanged()
{
Servo_StyleSet_NoteStyleSheetsChanged(mRawSet.get());
--- a/layout/style/ServoStyleSet.h
+++ b/layout/style/ServoStyleSet.h
@@ -297,17 +297,18 @@ private:
*/
void ResolveMappedAttrDeclarationBlocks();
/**
* Perform all lazy operations required before traversing
* a subtree. Returns whether a post-traversal is required.
*/
bool PrepareAndTraverseSubtree(RawGeckoElementBorrowed aRoot,
- mozilla::TraversalRootBehavior aRootBehavior);
+ TraversalRootBehavior aRootBehavior,
+ TraversalRestyleBehavior aRestyleBehavior);
/**
* Clear our cached mNonInheritingStyleContexts. We do this when we want to
* make sure those style contexts won't live too long (e.g. when rebuilding
* all style data or when shutting down the style set).
*/
void ClearNonInheritingStyleContexts();
--- a/layout/style/ServoTypes.h
+++ b/layout/style/ServoTypes.h
@@ -48,16 +48,26 @@ enum class LazyComputeBehavior {
// 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 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.
+enum class TraversalRestyleBehavior {
+ Normal,
+ ForReconstruct,
+};
+
// Represents which tasks are performed in a SequentialTask of UpdateAnimations.
enum class UpdateAnimationsTasks : uint8_t {
CSSAnimations = 1 << 0,
CSSTransitions = 1 << 1,
EffectProperties = 1 << 2,
CascadeResults = 1 << 3,
};