Bug 1334036 - Part 3: Add a flag to represent we are in pre-traversal.
We need this flag to avoid assertion in PostRestyleForAnimation(), which
may be called from MaybeUpdateCascadeResults() in pre-traversal.
MozReview-Commit-ID: 46AfoIUb9o3
--- a/dom/animation/EffectCompositor.cpp
+++ b/dom/animation/EffectCompositor.cpp
@@ -8,16 +8,17 @@
#include "mozilla/dom/Animation.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/KeyframeEffectReadOnly.h"
#include "mozilla/AnimationComparator.h"
#include "mozilla/AnimationPerformanceWarning.h"
#include "mozilla/AnimationTarget.h"
#include "mozilla/AnimationUtils.h"
+#include "mozilla/AutoRestore.h"
#include "mozilla/EffectSet.h"
#include "mozilla/LayerAnimationInfo.h"
#include "mozilla/RestyleManager.h"
#include "mozilla/RestyleManagerInlines.h"
#include "mozilla/ServoStyleSet.h"
#include "mozilla/StyleAnimationValue.h"
#include "mozilla/TypeTraits.h" // For Forward<>
#include "nsComputedDOMStyle.h" // nsComputedDOMStyle::GetPresShellForContent
@@ -310,17 +311,17 @@ EffectCompositor::PostRestyleForAnimatio
nsRestyleHint hint = aCascadeLevel == CascadeLevel::Transitions ?
eRestyle_CSSTransitions :
eRestyle_CSSAnimations;
if (mPresContext->StyleSet()->IsServo()) {
MOZ_ASSERT(NS_IsMainThread(),
"Restyle request during restyling should be requested only on "
"the main-thread. e.g. after the parallel traversal");
- if (ServoStyleSet::IsInServoTraversal()) {
+ if (ServoStyleSet::IsInServoTraversal() || mIsInPreTraverse) {
MOZ_ASSERT(hint == eRestyle_CSSAnimations ||
hint == eRestyle_CSSTransitions);
// We can't call Servo_NoteExplicitHints here since AtomicRefCell does not
// allow us mutate ElementData of the |aElement| in SequentialTask.
// Instead we call Servo_NoteExplicitHints for the element in PreTraverse()
// which will be called right before the second traversal that we do for
// updating CSS animations.
@@ -955,16 +956,19 @@ EffectCompositor::PreTraverse()
}
bool
EffectCompositor::PreTraverseInSubtree(Element* aRoot)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mPresContext->RestyleManager()->IsServo());
+ AutoRestore<bool> guard(mIsInPreTraverse);
+ mIsInPreTraverse = true;
+
// We need to force flush all throttled animations if there are any
// non-animation restyles.
bool flushThrottledRestyles = aRoot && aRoot->HasDirtyDescendantsForServo();
using ElementsToRestyleIterType =
nsDataHashtable<PseudoElementHashEntry, bool>::Iterator;
auto getNeededRestyleTarget = [&](const ElementsToRestyleIterType& aIter)
-> NonOwningAnimationTarget {
@@ -1069,16 +1073,19 @@ EffectCompositor::PreTraverse(dom::Eleme
bool found = false;
if (aPseudoType != CSSPseudoElementType::NotPseudo &&
aPseudoType != CSSPseudoElementType::before &&
aPseudoType != CSSPseudoElementType::after) {
return found;
}
+ AutoRestore<bool> guard(mIsInPreTraverse);
+ mIsInPreTraverse = true;
+
PseudoElementHashEntry::KeyType key = { aElement, aPseudoType };
// We need to flush all throttled animation restyles too if there are
// any non-animation restyles.
Element* elementToRestyle = GetElementToRestyle(aElement, aPseudoType);
bool flushThrottledRestyles = elementToRestyle &&
elementToRestyle->HasDirtyDescendantsForServo();
--- a/dom/animation/EffectCompositor.h
+++ b/dom/animation/EffectCompositor.h
@@ -288,16 +288,18 @@ private:
// true if a pending animation restyle has also been dispatched. For
// animations that can be throttled, we will add an entry to the hashtable to
// indicate that the style rule on the element is out of date but without
// posting a restyle to update it.
EnumeratedArray<CascadeLevel, CascadeLevel(kCascadeLevelCount),
nsDataHashtable<PseudoElementHashEntry, bool>>
mElementsToRestyle;
+ bool mIsInPreTraverse = false;
+
class AnimationStyleRuleProcessor final : public nsIStyleRuleProcessor
{
public:
AnimationStyleRuleProcessor(EffectCompositor* aCompositor,
CascadeLevel aCascadeLevel)
: mCompositor(aCompositor)
, mCascadeLevel(aCascadeLevel)
{