diff --git a/dom/animation/AnimationTimeline.cpp b/dom/animation/AnimationTimeline.cpp index 8be0554683575..cd6c844655529 100644 --- a/dom/animation/AnimationTimeline.cpp +++ b/dom/animation/AnimationTimeline.cpp @@ -41,41 +41,33 @@ AnimationTimeline::~AnimationTimeline() { mAnimationOrder.clear(); } bool AnimationTimeline::Tick() { bool needsTicks = false; - nsTArray animationsToRemove; - - for (Animation* animation = mAnimationOrder.getFirst(); animation; - animation = - static_cast*>(animation)->getNext()) { + AutoTArray, 32> animationsToTick; + for (Animation* animation : mAnimationOrder) { MOZ_ASSERT(mAnimations.Contains(animation), "The sampling order list should be a subset of the hashset"); MOZ_ASSERT(!animation->IsHiddenByContentVisibility(), "The sampling order list should not contain any animations " "that are hidden by content-visibility"); + animationsToTick.AppendElement(animation); + } + for (Animation* animation : animationsToTick) { // Skip any animations that are longer need associated with this timeline. if (animation->GetTimeline() != this) { - // If animation has some other timeline, it better not be also in the - // animation list of this timeline object! - MOZ_ASSERT(!animation->GetTimeline()); - animationsToRemove.AppendElement(animation); + RemoveAnimation(animation); continue; } needsTicks |= animation->NeedsTicks(); - // Even if |animation| doesn't need future ticks, we should still - // Tick it this time around since it might just need a one-off tick in - // order to dispatch events. + // Even if |animation| doesn't need future ticks, we should still Tick it + // this time around since it might just need a one-off tick in order to + // dispatch events. animation->Tick(); - if (!animation->NeedsTicks()) { - animationsToRemove.AppendElement(animation); + RemoveAnimation(animation); } } - for (Animation* animation : animationsToRemove) { - RemoveAnimation(animation); - } - return needsTicks; } @@ -91,11 +83,12 @@ void AnimationTimeline::NotifyAnimationUpdated(Animation& aAnimation) { } void AnimationTimeline::RemoveAnimation(Animation* aAnimation) { - MOZ_ASSERT(!aAnimation->GetTimeline() || aAnimation->GetTimeline() == this); - if (static_cast*>(aAnimation)->isInList()) { + if (static_cast*>(aAnimation)->isInList() && + MOZ_LIKELY(!aAnimation->GetTimeline() || + aAnimation->GetTimeline() == this)) { + static_cast*>(aAnimation)->remove(); MOZ_ASSERT(mAnimations.Contains(aAnimation), "The sampling order list should be a subset of the hashset"); - static_cast*>(aAnimation)->remove(); } mAnimations.Remove(aAnimation); } diff --git a/dom/animation/ScrollTimelineAnimationTracker.cpp b/dom/animation/ScrollTimelineAnimationTracker.cpp index ae46bca62bda3..18a98b7aa10cf 100644 --- a/dom/animation/ScrollTimelineAnimationTracker.cpp +++ b/dom/animation/ScrollTimelineAnimationTracker.cpp @@ -13,13 +13,10 @@ namespace mozilla { NS_IMPL_CYCLE_COLLECTION(ScrollTimelineAnimationTracker, mPendingSet, mDocument) void ScrollTimelineAnimationTracker::TriggerPendingAnimations() { - for (auto iter = mPendingSet.begin(), end = mPendingSet.end(); iter != end; - ++iter) { - dom::Animation* animation = *iter; - + for (RefPtr& animation : + ToTArray, 32>>(mPendingSet)) { MOZ_ASSERT(animation->GetTimeline() && !animation->GetTimeline()->IsMonotonicallyIncreasing()); - // FIXME: Trigger now may not be correct because the spec says: // If a user agent determines that animation is immediately ready, it may // schedule the task (i.e. ResumeAt()) as a microtask such that it runs at @@ -39,9 +36,7 @@ void ScrollTimelineAnimationTracker::TriggerPendingAnimations() { // inactive, and this also matches the current spec definition. continue; } - - // Note: Remove() is legitimately called once per entry during the loop. - mPendingSet.Remove(iter); + mPendingSet.Remove(animation); } }