Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(233)

Side by Side Diff: third_party/WebKit/Source/core/animation/DocumentTimeline.cpp

Issue 2948193002: Merge AnimationTimeline and DocumentTimeline (Closed)
Patch Set: Fix rebase error Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698