AnimationTimeline.cpp (4125B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "AnimationTimeline.h" 8 9 #include "mozilla/dom/Animation.h" 10 11 namespace mozilla::dom { 12 13 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(AnimationTimeline) 14 15 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(AnimationTimeline) 16 tmp->mAnimationOrder.clear(); 17 NS_IMPL_CYCLE_COLLECTION_UNLINK(mWindow, mAnimations) 18 NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER 19 NS_IMPL_CYCLE_COLLECTION_UNLINK_END 20 21 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(AnimationTimeline) 22 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWindow, mAnimations) 23 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END 24 25 NS_IMPL_CYCLE_COLLECTING_ADDREF(AnimationTimeline) 26 NS_IMPL_CYCLE_COLLECTING_RELEASE(AnimationTimeline) 27 28 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(AnimationTimeline) 29 NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY 30 NS_INTERFACE_MAP_ENTRY(nsISupports) 31 NS_INTERFACE_MAP_END 32 33 AnimationTimeline::AnimationTimeline(nsIGlobalObject* aWindow, 34 RTPCallerType aRTPCallerType) 35 : mWindow(aWindow), mRTPCallerType(aRTPCallerType) { 36 MOZ_ASSERT(mWindow); 37 } 38 39 AnimationTimeline::~AnimationTimeline() { mAnimationOrder.clear(); } 40 41 bool AnimationTimeline::Tick(TickState& aState) { 42 bool needsTicks = false; 43 44 #ifdef DEBUG 45 for (Animation* animation : mAnimationOrder) { 46 MOZ_ASSERT(mAnimations.Contains(animation), 47 "The sampling order list should be a subset of the hashset"); 48 MOZ_ASSERT(!animation->IsHiddenByContentVisibility(), 49 "The sampling order list should not contain any animations " 50 "that are hidden by content-visibility"); 51 } 52 #endif 53 54 for (Animation* animation : 55 ToTArray<AutoTArray<RefPtr<Animation>, 32>>(mAnimationOrder)) { 56 // Skip any animations that are longer need associated with this timeline. 57 if (animation->GetTimeline() != this) { 58 RemoveAnimation(animation); 59 continue; 60 } 61 62 needsTicks |= animation->NeedsTicks(); 63 // Even if |animation| doesn't need future ticks, we should still Tick it 64 // this time around since it might just need a one-off tick in order to 65 // queue events. 66 animation->Tick(aState); 67 if (!animation->NeedsTicks()) { 68 RemoveAnimation(animation); 69 } 70 } 71 72 return needsTicks; 73 } 74 75 void AnimationTimeline::NotifyAnimationUpdated(Animation& aAnimation) { 76 if (mAnimations.EnsureInserted(&aAnimation)) { 77 if (aAnimation.GetTimeline() && aAnimation.GetTimeline() != this) { 78 aAnimation.GetTimeline()->RemoveAnimation(&aAnimation); 79 } 80 if (!aAnimation.IsHiddenByContentVisibility()) { 81 mAnimationOrder.insertBack(&aAnimation); 82 } 83 } 84 } 85 86 void AnimationTimeline::RemoveAnimation(Animation* aAnimation) { 87 if (static_cast<LinkedListElement<Animation>*>(aAnimation)->isInList() && 88 MOZ_LIKELY(!aAnimation->GetTimeline() || 89 aAnimation->GetTimeline() == this)) { 90 static_cast<LinkedListElement<Animation>*>(aAnimation)->remove(); 91 MOZ_ASSERT(mAnimations.Contains(aAnimation), 92 "The sampling order list should be a subset of the hashset"); 93 } 94 mAnimations.Remove(aAnimation); 95 } 96 97 void AnimationTimeline::NotifyAnimationContentVisibilityChanged( 98 Animation* aAnimation, bool aIsVisible) { 99 bool inList = 100 static_cast<LinkedListElement<Animation>*>(aAnimation)->isInList(); 101 MOZ_ASSERT(!inList || mAnimations.Contains(aAnimation), 102 "The sampling order list should be a subset of the hashset"); 103 if (aIsVisible && !inList && mAnimations.Contains(aAnimation)) { 104 mAnimationOrder.insertBack(aAnimation); 105 } else if (!aIsVisible && inList) { 106 static_cast<LinkedListElement<Animation>*>(aAnimation)->remove(); 107 } 108 } 109 110 void AnimationTimeline::UpdateHiddenByContentVisibility() { 111 for (Animation* animation : mAnimations) { 112 animation->UpdateHiddenByContentVisibility(); 113 } 114 } 115 116 } // namespace mozilla::dom