Bug 1228229 part 4 - Add a flag to EffectSet to mark when the cascade needs to be updated; r=dbaron

There are three situations when the cascade results of effects needs to be
updated.

1. The sets of effects (animations) has changed.

2. One or more effects have changed their "in effect" status.

3. Other style properties affecting the element have changing meaning that
   animations applied at the animations-level of the cascade may now be
   overridden or become active again.

We want to detect these situations so we can avoid updating the cascade when
none of these possibilities exist.

Currently we handle case 1 by calling UpdateCascadeResults at the appropriate
point in nsAnimationManager and nsTransitionManager when we build
animations/transtiions.

Case 2 only affects animations (since whether transitions are in effect or not
makes no difference to the cascade--they have a lower "composite order" than
animations and never overlap with each other so they can't override anything).
As a result, we handle it by adding a flag to CSSAnimation to track when an
animation was in effect last time we checked or not.

For case 3, we take care to call UpdateCascadeResults when the style context
changed in nsAnimationManager::CheckAnimationRule (called from
nsStyleSet::GetContext).

We want to generalize this detection to handle script-generated animations too.
In order to do that this patch introduces a flag to EffectSet that we will use
to mark when the cascade needs to be updated in cases 1 and 2. This patch also
sets the flag when we detect case 1. A subsequent patch sets the flag for
case 2.

Case 3 is more difficult to detect and so we simply maintain the existing
behavior of making nsAnimationManager::CheckAnimationRule unconditionally
update the cascade without checking if the "needs update" flag is set.
This commit is contained in:
Brian Birtles 2016-01-06 11:04:04 +09:00
parent 07d945ecb0
commit 1caec204db
2 changed files with 23 additions and 1 deletions

View File

@ -143,13 +143,23 @@ EffectSet::GetEffectSetPropertyAtom(nsCSSPseudoElements::Type aPseudoType)
void
EffectSet::AddEffect(dom::KeyframeEffectReadOnly& aEffect)
{
if (mEffects.Contains(&aEffect)) {
return;
}
mEffects.PutEntry(&aEffect);
MarkCascadeNeedsUpdate();
}
void
EffectSet::RemoveEffect(dom::KeyframeEffectReadOnly& aEffect)
{
if (!mEffects.Contains(&aEffect)) {
return;
}
mEffects.RemoveEntry(&aEffect);
MarkCascadeNeedsUpdate();
}
} // namespace mozilla

View File

@ -24,8 +24,9 @@ class EffectSet
{
public:
EffectSet()
: mCascadeNeedsUpdate(false)
#ifdef DEBUG
: mCalledPropertyDtor(false)
, mCalledPropertyDtor(false)
#endif
{
MOZ_COUNT_CTOR(EffectSet);
@ -120,6 +121,10 @@ public:
}
bool IsEmpty() const { return mEffects.IsEmpty(); }
bool CascadeNeedsUpdate() const { return mCascadeNeedsUpdate; }
void MarkCascadeNeedsUpdate() { mCascadeNeedsUpdate = true; }
void MarkCascadeUpdated() { mCascadeNeedsUpdate = false; }
static nsIAtom** GetEffectSetPropertyAtoms();
private:
@ -128,6 +133,13 @@ private:
OwningEffectSet mEffects;
// Dirty flag to represent when the mWinsInCascade flag on effects in
// this set might need to be updated.
//
// Set to true any time the set of effects is changed or when
// one the effects goes in or out of the "in effect" state.
bool mCascadeNeedsUpdate;
#ifdef DEBUG
bool mCalledPropertyDtor;
#endif