| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 29 */ | 29 */ |
| 30 | 30 |
| 31 #include "core/animation/AnimationTimeline.h" | 31 #include "core/animation/DocumentTimeline.h" |
| 32 | 32 |
| 33 #include <algorithm> | 33 #include <algorithm> |
| 34 #include "core/animation/AnimationClock.h" | 34 #include "core/animation/AnimationClock.h" |
| 35 #include "core/animation/ElementAnimations.h" | 35 #include "core/animation/ElementAnimations.h" |
| 36 #include "core/dom/Document.h" | 36 #include "core/dom/Document.h" |
| 37 #include "core/frame/LocalFrameView.h" | 37 #include "core/frame/LocalFrameView.h" |
| 38 #include "core/loader/DocumentLoader.h" | 38 #include "core/loader/DocumentLoader.h" |
| 39 #include "core/page/Page.h" | 39 #include "core/page/Page.h" |
| 40 #include "platform/RuntimeEnabledFeatures.h" | 40 #include "platform/RuntimeEnabledFeatures.h" |
| 41 #include "platform/animation/CompositorAnimationTimeline.h" | 41 #include "platform/animation/CompositorAnimationTimeline.h" |
| 42 #include "platform/instrumentation/tracing/TraceEvent.h" | 42 #include "platform/instrumentation/tracing/TraceEvent.h" |
| 43 #include "platform/wtf/PtrUtil.h" | 43 #include "platform/wtf/PtrUtil.h" |
| 44 #include "public/platform/Platform.h" | 44 #include "public/platform/Platform.h" |
| 45 #include "public/platform/WebCompositorSupport.h" | 45 #include "public/platform/WebCompositorSupport.h" |
| 46 | 46 |
| 47 namespace blink { | 47 namespace blink { |
| 48 | 48 |
| 49 namespace { | 49 namespace { |
| 50 | 50 |
| 51 bool CompareAnimations(const Member<Animation>& left, | 51 bool CompareAnimations(const Member<Animation>& left, |
| 52 const Member<Animation>& right) { | 52 const Member<Animation>& right) { |
| 53 return Animation::HasLowerPriority(left.Get(), right.Get()); | 53 return Animation::HasLowerPriority(left.Get(), right.Get()); |
| 54 } | 54 } |
| 55 } | 55 } // namespace |
| 56 | 56 |
| 57 // This value represents 1 frame at 30Hz plus a little bit of wiggle room. | 57 // This value represents 1 frame at 30Hz plus a little bit of wiggle room. |
| 58 // TODO: Plumb a nominal framerate through and derive this value from that. | 58 // TODO: Plumb a nominal framerate through and derive this value from that. |
| 59 const double AnimationTimeline::kMinimumDelay = 0.04; | 59 const double DocumentTimeline::kMinimumDelay = 0.04; |
| 60 | 60 |
| 61 AnimationTimeline* AnimationTimeline::Create(Document* document, | 61 DocumentTimeline* DocumentTimeline::Create(Document* document, |
| 62 PlatformTiming* timing) { | 62 PlatformTiming* timing) { |
| 63 return new AnimationTimeline(document, timing); | 63 return new DocumentTimeline(document, timing); |
| 64 } | 64 } |
| 65 | 65 |
| 66 AnimationTimeline::AnimationTimeline(Document* document, PlatformTiming* timing) | 66 DocumentTimeline::DocumentTimeline(Document* document, PlatformTiming* timing) |
| 67 : document_(document), | 67 : document_(document), |
| 68 // 0 is used by unit tests which cannot initialize from the loader | 68 // 0 is used by unit tests which cannot initialize from the loader |
| 69 zero_time_(0), | 69 zero_time_(0), |
| 70 zero_time_initialized_(false), | 70 zero_time_initialized_(false), |
| 71 outdated_animation_count_(0), | 71 outdated_animation_count_(0), |
| 72 playback_rate_(1), | 72 playback_rate_(1), |
| 73 last_current_time_internal_(0) { | 73 last_current_time_internal_(0) { |
| 74 if (!timing) | 74 if (!timing) |
| 75 timing_ = new AnimationTimelineTiming(this); | 75 timing_ = new DocumentTimelineTiming(this); |
| 76 else | 76 else |
| 77 timing_ = timing; | 77 timing_ = timing; |
| 78 | 78 |
| 79 if (Platform::Current()->IsThreadedAnimationEnabled()) | 79 if (Platform::Current()->IsThreadedAnimationEnabled()) |
| 80 compositor_timeline_ = CompositorAnimationTimeline::Create(); | 80 compositor_timeline_ = CompositorAnimationTimeline::Create(); |
| 81 | 81 |
| 82 DCHECK(document); | 82 DCHECK(document); |
| 83 } | 83 } |
| 84 | 84 |
| 85 bool AnimationTimeline::IsActive() { | 85 bool DocumentTimeline::IsActive() { |
| 86 return document_ && document_->GetPage(); | 86 return document_ && document_->GetPage(); |
| 87 } | 87 } |
| 88 | 88 |
| 89 void AnimationTimeline::AnimationAttached(Animation& animation) { | 89 void DocumentTimeline::AnimationAttached(Animation& animation) { |
| 90 DCHECK_EQ(animation.TimelineInternal(), this); | 90 DCHECK_EQ(animation.TimelineInternal(), this); |
| 91 DCHECK(!animations_.Contains(&animation)); | 91 DCHECK(!animations_.Contains(&animation)); |
| 92 animations_.insert(&animation); | 92 animations_.insert(&animation); |
| 93 } | 93 } |
| 94 | 94 |
| 95 Animation* AnimationTimeline::Play(AnimationEffectReadOnly* child) { | 95 Animation* DocumentTimeline::Play(AnimationEffectReadOnly* child) { |
| 96 if (!document_) | 96 if (!document_) |
| 97 return nullptr; | 97 return nullptr; |
| 98 | 98 |
| 99 Animation* animation = Animation::Create(child, this); | 99 Animation* animation = Animation::Create(child, this); |
| 100 DCHECK(animations_.Contains(animation)); | 100 DCHECK(animations_.Contains(animation)); |
| 101 | 101 |
| 102 animation->play(); | 102 animation->play(); |
| 103 DCHECK(animations_needing_update_.Contains(animation)); | 103 DCHECK(animations_needing_update_.Contains(animation)); |
| 104 | 104 |
| 105 return animation; | 105 return animation; |
| 106 } | 106 } |
| 107 | 107 |
| 108 HeapVector<Member<Animation>> AnimationTimeline::getAnimations() { | 108 HeapVector<Member<Animation>> DocumentTimeline::getAnimations() { |
| 109 HeapVector<Member<Animation>> animations; | 109 HeapVector<Member<Animation>> animations; |
| 110 for (const auto& animation : animations_) { | 110 for (const auto& animation : animations_) { |
| 111 if (animation->effect() && | 111 if (animation->effect() && |
| 112 (animation->effect()->IsCurrent() || animation->effect()->IsInEffect())) | 112 (animation->effect()->IsCurrent() || animation->effect()->IsInEffect())) |
| 113 animations.push_back(animation); | 113 animations.push_back(animation); |
| 114 } | 114 } |
| 115 std::sort(animations.begin(), animations.end(), CompareAnimations); | 115 std::sort(animations.begin(), animations.end(), CompareAnimations); |
| 116 return animations; | 116 return animations; |
| 117 } | 117 } |
| 118 | 118 |
| 119 void AnimationTimeline::Wake() { | 119 void DocumentTimeline::Wake() { |
| 120 timing_->ServiceOnNextFrame(); | 120 timing_->ServiceOnNextFrame(); |
| 121 } | 121 } |
| 122 | 122 |
| 123 void AnimationTimeline::ServiceAnimations(TimingUpdateReason reason) { | 123 void DocumentTimeline::ServiceAnimations(TimingUpdateReason reason) { |
| 124 TRACE_EVENT0("blink", "AnimationTimeline::serviceAnimations"); | 124 TRACE_EVENT0("blink", "DocumentTimeline::serviceAnimations"); |
| 125 | 125 |
| 126 last_current_time_internal_ = CurrentTimeInternal(); | 126 last_current_time_internal_ = CurrentTimeInternal(); |
| 127 | 127 |
| 128 HeapVector<Member<Animation>> animations; | 128 HeapVector<Member<Animation>> animations; |
| 129 animations.ReserveInitialCapacity(animations_needing_update_.size()); | 129 animations.ReserveInitialCapacity(animations_needing_update_.size()); |
| 130 for (Animation* animation : animations_needing_update_) | 130 for (Animation* animation : animations_needing_update_) |
| 131 animations.push_back(animation); | 131 animations.push_back(animation); |
| 132 | 132 |
| 133 std::sort(animations.begin(), animations.end(), Animation::HasLowerPriority); | 133 std::sort(animations.begin(), animations.end(), Animation::HasLowerPriority); |
| 134 | 134 |
| 135 for (Animation* animation : animations) { | 135 for (Animation* animation : animations) { |
| 136 if (!animation->Update(reason)) | 136 if (!animation->Update(reason)) |
| 137 animations_needing_update_.erase(animation); | 137 animations_needing_update_.erase(animation); |
| 138 } | 138 } |
| 139 | 139 |
| 140 DCHECK_EQ(outdated_animation_count_, 0U); | 140 DCHECK_EQ(outdated_animation_count_, 0U); |
| 141 DCHECK(last_current_time_internal_ == CurrentTimeInternal() || | 141 DCHECK(last_current_time_internal_ == CurrentTimeInternal() || |
| 142 (std::isnan(CurrentTimeInternal()) && | 142 (std::isnan(CurrentTimeInternal()) && |
| 143 std::isnan(last_current_time_internal_))); | 143 std::isnan(last_current_time_internal_))); |
| 144 | 144 |
| 145 #if DCHECK_IS_ON() | 145 #if DCHECK_IS_ON() |
| 146 for (const auto& animation : animations_needing_update_) | 146 for (const auto& animation : animations_needing_update_) |
| 147 DCHECK(!animation->Outdated()); | 147 DCHECK(!animation->Outdated()); |
| 148 #endif | 148 #endif |
| 149 } | 149 } |
| 150 | 150 |
| 151 void AnimationTimeline::ScheduleNextService() { | 151 void DocumentTimeline::ScheduleNextService() { |
| 152 DCHECK_EQ(outdated_animation_count_, 0U); | 152 DCHECK_EQ(outdated_animation_count_, 0U); |
| 153 | 153 |
| 154 double time_to_next_effect = std::numeric_limits<double>::infinity(); | 154 double time_to_next_effect = std::numeric_limits<double>::infinity(); |
| 155 for (const auto& animation : animations_needing_update_) { | 155 for (const auto& animation : animations_needing_update_) { |
| 156 time_to_next_effect = | 156 time_to_next_effect = |
| 157 std::min(time_to_next_effect, animation->TimeToEffectChange()); | 157 std::min(time_to_next_effect, animation->TimeToEffectChange()); |
| 158 } | 158 } |
| 159 | 159 |
| 160 if (time_to_next_effect < kMinimumDelay) { | 160 if (time_to_next_effect < kMinimumDelay) { |
| 161 timing_->ServiceOnNextFrame(); | 161 timing_->ServiceOnNextFrame(); |
| 162 } else if (time_to_next_effect != std::numeric_limits<double>::infinity()) { | 162 } else if (time_to_next_effect != std::numeric_limits<double>::infinity()) { |
| 163 timing_->WakeAfter(time_to_next_effect - kMinimumDelay); | 163 timing_->WakeAfter(time_to_next_effect - kMinimumDelay); |
| 164 } | 164 } |
| 165 } | 165 } |
| 166 | 166 |
| 167 void AnimationTimeline::AnimationTimelineTiming::WakeAfter(double duration) { | 167 void DocumentTimeline::DocumentTimelineTiming::WakeAfter(double duration) { |
| 168 if (timer_.IsActive() && timer_.NextFireInterval() < duration) | 168 if (timer_.IsActive() && timer_.NextFireInterval() < duration) |
| 169 return; | 169 return; |
| 170 timer_.StartOneShot(duration, BLINK_FROM_HERE); | 170 timer_.StartOneShot(duration, BLINK_FROM_HERE); |
| 171 } | 171 } |
| 172 | 172 |
| 173 void AnimationTimeline::AnimationTimelineTiming::ServiceOnNextFrame() { | 173 void DocumentTimeline::DocumentTimelineTiming::ServiceOnNextFrame() { |
| 174 if (timeline_->document_ && timeline_->document_->View()) | 174 if (timeline_->document_ && timeline_->document_->View()) |
| 175 timeline_->document_->View()->ScheduleAnimation(); | 175 timeline_->document_->View()->ScheduleAnimation(); |
| 176 } | 176 } |
| 177 | 177 |
| 178 DEFINE_TRACE(AnimationTimeline::AnimationTimelineTiming) { | 178 DEFINE_TRACE(DocumentTimeline::DocumentTimelineTiming) { |
| 179 visitor->Trace(timeline_); | 179 visitor->Trace(timeline_); |
| 180 AnimationTimeline::PlatformTiming::Trace(visitor); | 180 DocumentTimeline::PlatformTiming::Trace(visitor); |
| 181 } | 181 } |
| 182 | 182 |
| 183 double AnimationTimeline::ZeroTime() { | 183 double DocumentTimeline::ZeroTime() { |
| 184 if (!zero_time_initialized_ && document_ && document_->Loader()) { | 184 if (!zero_time_initialized_ && document_ && document_->Loader()) { |
| 185 zero_time_ = document_->Loader()->GetTiming().ReferenceMonotonicTime(); | 185 zero_time_ = document_->Loader()->GetTiming().ReferenceMonotonicTime(); |
| 186 zero_time_initialized_ = true; | 186 zero_time_initialized_ = true; |
| 187 } | 187 } |
| 188 return zero_time_; | 188 return zero_time_; |
| 189 } | 189 } |
| 190 | 190 |
| 191 void AnimationTimeline::ResetForTesting() { | 191 void DocumentTimeline::ResetForTesting() { |
| 192 zero_time_ = 0; | 192 zero_time_ = 0; |
| 193 zero_time_initialized_ = true; | 193 zero_time_initialized_ = true; |
| 194 playback_rate_ = 1; | 194 playback_rate_ = 1; |
| 195 last_current_time_internal_ = 0; | 195 last_current_time_internal_ = 0; |
| 196 } | 196 } |
| 197 | 197 |
| 198 double AnimationTimeline::currentTime(bool& is_null) { | 198 double DocumentTimeline::currentTime(bool& is_null) { |
| 199 return CurrentTimeInternal(is_null) * 1000; | 199 return CurrentTimeInternal(is_null) * 1000; |
| 200 } | 200 } |
| 201 | 201 |
| 202 double AnimationTimeline::CurrentTimeInternal(bool& is_null) { | 202 double DocumentTimeline::CurrentTimeInternal(bool& is_null) { |
| 203 if (!IsActive()) { | 203 if (!IsActive()) { |
| 204 is_null = true; | 204 is_null = true; |
| 205 return std::numeric_limits<double>::quiet_NaN(); | 205 return std::numeric_limits<double>::quiet_NaN(); |
| 206 } | 206 } |
| 207 double result = | 207 double result = |
| 208 playback_rate_ == 0 | 208 playback_rate_ == 0 |
| 209 ? ZeroTime() | 209 ? ZeroTime() |
| 210 : (GetDocument()->GetAnimationClock().CurrentTime() - ZeroTime()) * | 210 : (GetDocument()->GetAnimationClock().CurrentTime() - ZeroTime()) * |
| 211 playback_rate_; | 211 playback_rate_; |
| 212 is_null = std::isnan(result); | 212 is_null = std::isnan(result); |
| 213 return result; | 213 return result; |
| 214 } | 214 } |
| 215 | 215 |
| 216 double AnimationTimeline::currentTime() { | 216 double DocumentTimeline::currentTime() { |
| 217 return CurrentTimeInternal() * 1000; | 217 return CurrentTimeInternal() * 1000; |
| 218 } | 218 } |
| 219 | 219 |
| 220 double AnimationTimeline::CurrentTimeInternal() { | 220 double DocumentTimeline::CurrentTimeInternal() { |
| 221 bool is_null; | 221 bool is_null; |
| 222 return CurrentTimeInternal(is_null); | 222 return CurrentTimeInternal(is_null); |
| 223 } | 223 } |
| 224 | 224 |
| 225 double AnimationTimeline::EffectiveTime() { | 225 double DocumentTimeline::EffectiveTime() { |
| 226 double time = CurrentTimeInternal(); | 226 double time = CurrentTimeInternal(); |
| 227 return std::isnan(time) ? 0 : time; | 227 return std::isnan(time) ? 0 : time; |
| 228 } | 228 } |
| 229 | 229 |
| 230 void AnimationTimeline::PauseAnimationsForTesting(double pause_time) { | 230 void DocumentTimeline::PauseAnimationsForTesting(double pause_time) { |
| 231 for (const auto& animation : animations_needing_update_) | 231 for (const auto& animation : animations_needing_update_) |
| 232 animation->PauseForTesting(pause_time); | 232 animation->PauseForTesting(pause_time); |
| 233 ServiceAnimations(kTimingUpdateOnDemand); | 233 ServiceAnimations(kTimingUpdateOnDemand); |
| 234 } | 234 } |
| 235 | 235 |
| 236 bool AnimationTimeline::NeedsAnimationTimingUpdate() { | 236 bool DocumentTimeline::NeedsAnimationTimingUpdate() { |
| 237 if (CurrentTimeInternal() == last_current_time_internal_) | 237 if (CurrentTimeInternal() == last_current_time_internal_) |
| 238 return false; | 238 return false; |
| 239 | 239 |
| 240 if (std::isnan(CurrentTimeInternal()) && | 240 if (std::isnan(CurrentTimeInternal()) && |
| 241 std::isnan(last_current_time_internal_)) | 241 std::isnan(last_current_time_internal_)) |
| 242 return false; | 242 return false; |
| 243 | 243 |
| 244 // We allow m_lastCurrentTimeInternal to advance here when there | 244 // We allow m_lastCurrentTimeInternal to advance here when there |
| 245 // are no animations to allow animations spawned during style | 245 // are no animations to allow animations spawned during style |
| 246 // recalc to not invalidate this flag. | 246 // recalc to not invalidate this flag. |
| 247 if (animations_needing_update_.IsEmpty()) | 247 if (animations_needing_update_.IsEmpty()) |
| 248 last_current_time_internal_ = CurrentTimeInternal(); | 248 last_current_time_internal_ = CurrentTimeInternal(); |
| 249 | 249 |
| 250 return !animations_needing_update_.IsEmpty(); | 250 return !animations_needing_update_.IsEmpty(); |
| 251 } | 251 } |
| 252 | 252 |
| 253 void AnimationTimeline::ClearOutdatedAnimation(Animation* animation) { | 253 void DocumentTimeline::ClearOutdatedAnimation(Animation* animation) { |
| 254 DCHECK(!animation->Outdated()); | 254 DCHECK(!animation->Outdated()); |
| 255 outdated_animation_count_--; | 255 outdated_animation_count_--; |
| 256 } | 256 } |
| 257 | 257 |
| 258 void AnimationTimeline::SetOutdatedAnimation(Animation* animation) { | 258 void DocumentTimeline::SetOutdatedAnimation(Animation* animation) { |
| 259 DCHECK(animation->Outdated()); | 259 DCHECK(animation->Outdated()); |
| 260 outdated_animation_count_++; | 260 outdated_animation_count_++; |
| 261 animations_needing_update_.insert(animation); | 261 animations_needing_update_.insert(animation); |
| 262 if (IsActive() && !document_->GetPage()->Animator().IsServicingAnimations()) | 262 if (IsActive() && !document_->GetPage()->Animator().IsServicingAnimations()) |
| 263 timing_->ServiceOnNextFrame(); | 263 timing_->ServiceOnNextFrame(); |
| 264 } | 264 } |
| 265 | 265 |
| 266 void AnimationTimeline::SetPlaybackRate(double playback_rate) { | 266 void DocumentTimeline::SetPlaybackRate(double playback_rate) { |
| 267 if (!IsActive()) | 267 if (!IsActive()) |
| 268 return; | 268 return; |
| 269 double current_time = CurrentTimeInternal(); | 269 double current_time = CurrentTimeInternal(); |
| 270 playback_rate_ = playback_rate; | 270 playback_rate_ = playback_rate; |
| 271 zero_time_ = playback_rate == 0 | 271 zero_time_ = playback_rate == 0 |
| 272 ? current_time | 272 ? current_time |
| 273 : GetDocument()->GetAnimationClock().CurrentTime() - | 273 : GetDocument()->GetAnimationClock().CurrentTime() - |
| 274 current_time / playback_rate; | 274 current_time / playback_rate; |
| 275 zero_time_initialized_ = true; | 275 zero_time_initialized_ = true; |
| 276 | 276 |
| 277 // Corresponding compositor animation may need to be restarted to pick up | 277 // Corresponding compositor animation may need to be restarted to pick up |
| 278 // the new playback rate. Marking the effect changed forces this. | 278 // the new playback rate. Marking the effect changed forces this. |
| 279 SetAllCompositorPending(true); | 279 SetAllCompositorPending(true); |
| 280 } | 280 } |
| 281 | 281 |
| 282 void AnimationTimeline::SetAllCompositorPending(bool source_changed) { | 282 void DocumentTimeline::SetAllCompositorPending(bool source_changed) { |
| 283 for (const auto& animation : animations_) { | 283 for (const auto& animation : animations_) { |
| 284 animation->SetCompositorPending(source_changed); | 284 animation->SetCompositorPending(source_changed); |
| 285 } | 285 } |
| 286 } | 286 } |
| 287 | 287 |
| 288 double AnimationTimeline::PlaybackRate() const { | 288 double DocumentTimeline::PlaybackRate() const { |
| 289 return playback_rate_; | 289 return playback_rate_; |
| 290 } | 290 } |
| 291 | 291 |
| 292 void AnimationTimeline::InvalidateKeyframeEffects(const TreeScope& tree_scope) { | 292 void DocumentTimeline::InvalidateKeyframeEffects(const TreeScope& tree_scope) { |
| 293 for (const auto& animation : animations_) | 293 for (const auto& animation : animations_) |
| 294 animation->InvalidateKeyframeEffect(tree_scope); | 294 animation->InvalidateKeyframeEffect(tree_scope); |
| 295 } | 295 } |
| 296 | 296 |
| 297 DEFINE_TRACE(AnimationTimeline) { | 297 DEFINE_TRACE(DocumentTimeline) { |
| 298 visitor->Trace(document_); | 298 visitor->Trace(document_); |
| 299 visitor->Trace(timing_); | 299 visitor->Trace(timing_); |
| 300 visitor->Trace(animations_needing_update_); | 300 visitor->Trace(animations_needing_update_); |
| 301 visitor->Trace(animations_); | 301 visitor->Trace(animations_); |
| 302 SuperAnimationTimeline::Trace(visitor); | 302 SuperAnimationTimeline::Trace(visitor); |
| 303 } | 303 } |
| 304 | 304 |
| 305 } // namespace blink | 305 } // namespace blink |
| OLD | NEW |