Bug 1341985 - Trigger the second traversal for updating CSS animations in the case of Servo_ResolveStyleLazily. r?heycam
MozReview-Commit-ID: 7E4unP9M7FQ
--- a/dom/animation/EffectCompositor.cpp
+++ b/dom/animation/EffectCompositor.cpp
@@ -330,16 +330,18 @@ EffectCompositor::PostRestyleForAnimatio
// In that case PreTraverse() will return true so that we know to do the
// second traversal so we don't need to post any restyle requests to the
// PresShell.
return;
} else if (!mPresContext->RestyleManager()->IsInStyleRefresh()) {
// FIXME: stylo only supports Self and Subtree hints now, so we override
// it for stylo if we are not in process of restyling.
hint = eRestyle_Self | eRestyle_Subtree;
+ } else {
+ MOZ_ASSERT_UNREACHABLE("Should not request restyle");
}
}
mPresContext->PresShell()->RestyleForAnimation(element, hint);
}
void
EffectCompositor::PostRestyleForThrottledAnimations()
{
@@ -991,49 +993,55 @@ EffectCompositor::PreTraverse()
// Remove the element from the list of elements to restyle since we are
// about to restyle it.
iter.Remove();
}
}
return foundElementsNeedingRestyle;
}
-void
+bool
EffectCompositor::PreTraverse(dom::Element* aElement, nsIAtom* aPseudoTagOrNull)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mPresContext->RestyleManager()->IsServo());
+ bool found = false;
if (aPseudoTagOrNull &&
aPseudoTagOrNull != nsGkAtoms::cssPseudoElementBeforeProperty &&
aPseudoTagOrNull != nsGkAtoms::cssPseudoElementAfterProperty) {
- return;
+ return found;
}
CSSPseudoElementType pseudoType =
nsCSSPseudoElements::GetPseudoType(aPseudoTagOrNull,
CSSEnabledState::eForAllContent);
PseudoElementHashEntry::KeyType key = { aElement, pseudoType };
for (auto& elementsToRestyle : mElementsToRestyle) {
if (!elementsToRestyle.Get(key)) {
// Ignore throttled restyle and no restyle request.
continue;
}
+ mPresContext->RestyleManager()->AsServo()->
+ PostRestyleEventForAnimations(aElement, eRestyle_Self);
+
EffectSet* effects = EffectSet::GetEffectSet(aElement, pseudoType);
if (effects) {
for (KeyframeEffectReadOnly* effect : *effects) {
effect->GetAnimation()->WillComposeStyle();
}
}
elementsToRestyle.Remove(key);
+ found = true;
}
+ return found;
}
// ---------------------------------------------------------
//
// Nested class: AnimationStyleRuleProcessor
//
// ---------------------------------------------------------
--- a/dom/animation/EffectCompositor.h
+++ b/dom/animation/EffectCompositor.h
@@ -228,17 +228,17 @@ public:
// Do a bunch of stuff that we should avoid doing during the parallel
// traversal (e.g. changing member variables) for all elements that we expect
// to restyle on the next traversal.
// Returns true if there are elements needing a restyle for animation.
bool PreTraverse();
// Similar to the above but only for the (pseudo-)element.
- void PreTraverse(dom::Element* aElement, nsIAtom* aPseudoTagOrNull);
+ bool PreTraverse(dom::Element* aElement, nsIAtom* aPseudoTagOrNull);
private:
~EffectCompositor() = default;
// Rebuilds the animation rule corresponding to |aCascadeLevel| on the
// EffectSet associated with the specified (pseudo-)element.
static void ComposeAnimationRule(dom::Element* aElement,
CSSPseudoElementType aPseudoType,
--- a/layout/style/ServoStyleSet.cpp
+++ b/layout/style/ServoStyleSet.cpp
@@ -755,12 +755,23 @@ ServoStyleSet::ClearNonInheritingStyleCo
}
}
already_AddRefed<ServoComputedValues>
ServoStyleSet::ResolveStyleLazily(Element* aElement, nsIAtom* aPseudoTag)
{
mPresContext->EffectCompositor()->PreTraverse(aElement, aPseudoTag);
- return Servo_ResolveStyleLazily(aElement, aPseudoTag, mRawSet.get()).Consume();
+ MOZ_ASSERT(!sInServoTraversal);
+ sInServoTraversal = true;
+ RefPtr<ServoComputedValues> computedValues =
+ Servo_ResolveStyleLazily(aElement, aPseudoTag, mRawSet.get()).Consume();
+
+ if (mPresContext->EffectCompositor()->PreTraverse(aElement, aPseudoTag)) {
+ computedValues =
+ Servo_ResolveStyleLazily(aElement, aPseudoTag, mRawSet.get()).Consume();
+ }
+ sInServoTraversal = false;
+
+ return computedValues.forget();
}
bool ServoStyleSet::sInServoTraversal = false;