void EffectSet::RemoveEffect(dom::KeyframeEffect& aEffect) { if (!mEffects.EnsureRemoved(&aEffect)) { return; } MarkCascadeNeedsUpdate(); }
void EffectSet::RemoveEffect(dom::KeyframeEffectReadOnly& aEffect) { if (!mEffects.Contains(&aEffect)) { return; } mEffects.RemoveEntry(&aEffect); MarkCascadeNeedsUpdate(); }
void KeyframeEffectReadOnly::SetAnimation(Animation* aAnimation) { if (mAnimation == aAnimation) { return; } // Restyle for the old animation. RequestRestyle(EffectCompositor::RestyleType::Layer); mAnimation = aAnimation; // The order of these function calls is important: // NotifyAnimationTimingUpdated() need the updated mIsRelevant flag to check // if it should create the effectSet or not, and MarkCascadeNeedsUpdate() // needs a valid effectSet, so we should call them in this order. if (mAnimation) { mAnimation->UpdateRelevance(); } NotifyAnimationTimingUpdated(); if (mAnimation) { MarkCascadeNeedsUpdate(); } }
void KeyframeEffectReadOnly::UpdateProperties(nsStyleContext* aStyleContext) { MOZ_ASSERT(aStyleContext); nsTArray<AnimationProperty> properties = BuildProperties(aStyleContext); if (mProperties == properties) { return; } // Preserve the state of the mIsRunningOnCompositor flag. nsCSSPropertyIDSet runningOnCompositorProperties; for (const AnimationProperty& property : mProperties) { if (property.mIsRunningOnCompositor) { runningOnCompositorProperties.AddProperty(property.mProperty); } } mProperties = Move(properties); for (AnimationProperty& property : mProperties) { property.mIsRunningOnCompositor = runningOnCompositorProperties.HasProperty(property.mProperty); } // FIXME (bug 1303235): Do this for Servo too if (aStyleContext->PresContext()->StyleSet()->IsGecko()) { CalculateCumulativeChangeHint(aStyleContext); } MarkCascadeNeedsUpdate(); RequestRestyle(EffectCompositor::RestyleType::Layer); }
void KeyframeEffectReadOnly::UpdateProperties(nsStyleContext* aStyleContext) { MOZ_ASSERT(aStyleContext); nsTArray<AnimationProperty> properties; if (mTarget) { // When GetComputedKeyframeValues or GetAnimationPropertiesFromKeyframes // calculate computed values from |mKeyframes|, they could possibly // trigger a subsequent restyle in which we rebuild animations. If that // happens we could find that |mKeyframes| is overwritten while it is // being iterated over. Normally that shouldn't happen but just in case we // make a copy of |mKeyframes| first and iterate over that instead. auto keyframesCopy(mKeyframes); nsTArray<ComputedKeyframeValues> computedValues = KeyframeUtils::GetComputedKeyframeValues(keyframesCopy, mTarget->mElement, aStyleContext); if (mEffectOptions.mSpacingMode == SpacingMode::paced) { KeyframeUtils::ApplySpacing(keyframesCopy, SpacingMode::paced, mEffectOptions.mPacedProperty, computedValues); } properties = KeyframeUtils::GetAnimationPropertiesFromKeyframes(keyframesCopy, computedValues, aStyleContext); #ifdef DEBUG MOZ_ASSERT(SpecifiedKeyframeArraysAreEqual(mKeyframes, keyframesCopy), "Apart from the computed offset members, the keyframes array" " should not be modified"); #endif mKeyframes.SwapElements(keyframesCopy); } if (mProperties == properties) { return; } // Preserve the state of mWinsInCascade and mIsRunningOnCompositor flags. nsCSSPropertyIDSet winningInCascadeProperties; nsCSSPropertyIDSet runningOnCompositorProperties; for (const AnimationProperty& property : mProperties) { if (property.mWinsInCascade) { winningInCascadeProperties.AddProperty(property.mProperty); } if (property.mIsRunningOnCompositor) { runningOnCompositorProperties.AddProperty(property.mProperty); } } mProperties = Move(properties); for (AnimationProperty& property : mProperties) { property.mWinsInCascade = winningInCascadeProperties.HasProperty(property.mProperty); property.mIsRunningOnCompositor = runningOnCompositorProperties.HasProperty(property.mProperty); } CalculateCumulativeChangeHint(aStyleContext); MarkCascadeNeedsUpdate(); RequestRestyle(EffectCompositor::RestyleType::Layer); }