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 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
56 const double AnimationTimeline::s_minimumDelay = 0.04; | 56 const double AnimationTimeline::s_minimumDelay = 0.04; |
57 | 57 |
58 | 58 |
59 PassRefPtrWillBeRawPtr<AnimationTimeline> AnimationTimeline::create(Document* do
cument, PassOwnPtrWillBeRawPtr<PlatformTiming> timing) | 59 PassRefPtrWillBeRawPtr<AnimationTimeline> AnimationTimeline::create(Document* do
cument, PassOwnPtrWillBeRawPtr<PlatformTiming> timing) |
60 { | 60 { |
61 return adoptRefWillBeNoop(new AnimationTimeline(document, timing)); | 61 return adoptRefWillBeNoop(new AnimationTimeline(document, timing)); |
62 } | 62 } |
63 | 63 |
64 AnimationTimeline::AnimationTimeline(Document* document, PassOwnPtrWillBeRawPtr<
PlatformTiming> timing) | 64 AnimationTimeline::AnimationTimeline(Document* document, PassOwnPtrWillBeRawPtr<
PlatformTiming> timing) |
65 : m_document(document) | 65 : m_document(document) |
66 , m_zeroTime(0) | 66 , m_zeroTime(0) // 0 is used by unit tests which cannot initialize from the
loader |
67 , m_documentCurrentTimeSnapshot(0) | 67 , m_zeroTimeInitialized(false) |
68 , m_zeroTimeOffset(0) | |
69 , m_playbackRate(1) | 68 , m_playbackRate(1) |
70 , m_lastCurrentTimeInternal(0) | 69 , m_lastCurrentTimeInternal(0) |
71 { | 70 { |
72 if (!timing) | 71 if (!timing) |
73 m_timing = adoptPtrWillBeNoop(new AnimationTimelineTiming(this)); | 72 m_timing = adoptPtrWillBeNoop(new AnimationTimelineTiming(this)); |
74 else | 73 else |
75 m_timing = timing; | 74 m_timing = timing; |
76 | 75 |
77 ASSERT(document); | 76 ASSERT(document); |
78 } | 77 } |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
175 } | 174 } |
176 | 175 |
177 void AnimationTimeline::AnimationTimelineTiming::trace(Visitor* visitor) | 176 void AnimationTimeline::AnimationTimelineTiming::trace(Visitor* visitor) |
178 { | 177 { |
179 visitor->trace(m_timeline); | 178 visitor->trace(m_timeline); |
180 AnimationTimeline::PlatformTiming::trace(visitor); | 179 AnimationTimeline::PlatformTiming::trace(visitor); |
181 } | 180 } |
182 | 181 |
183 double AnimationTimeline::zeroTime() | 182 double AnimationTimeline::zeroTime() |
184 { | 183 { |
185 if (!m_zeroTime && m_document && m_document->loader()) { | 184 if (!m_zeroTimeInitialized && m_document && m_document->loader()) { |
186 m_zeroTime = m_document->loader()->timing()->referenceMonotonicTime(); | 185 m_zeroTime = m_document->loader()->timing()->referenceMonotonicTime(); |
| 186 m_zeroTimeInitialized = true; |
187 } | 187 } |
188 return m_zeroTime + m_zeroTimeOffset; | 188 return m_zeroTime; |
189 } | 189 } |
190 | 190 |
191 double AnimationTimeline::currentTime(bool& isNull) | 191 double AnimationTimeline::currentTime(bool& isNull) |
192 { | 192 { |
193 return currentTimeInternal(isNull) * 1000; | 193 return currentTimeInternal(isNull) * 1000; |
194 } | 194 } |
195 | 195 |
196 double AnimationTimeline::currentTimeInternal(bool& isNull) | 196 double AnimationTimeline::currentTimeInternal(bool& isNull) |
197 { | 197 { |
198 if (!m_document) { | 198 if (!m_document) { |
199 isNull = true; | 199 isNull = true; |
200 return std::numeric_limits<double>::quiet_NaN(); | 200 return std::numeric_limits<double>::quiet_NaN(); |
201 } | 201 } |
202 // New currentTime = currentTime when the playback rate was last changed + t
ime delta since then * playback rate | 202 double result = m_playbackRate == 0 |
203 double delta = document()->animationClock().currentTime() - m_documentCurren
tTimeSnapshot; | 203 ? zeroTime() |
204 double result = m_documentCurrentTimeSnapshot - zeroTime() + delta * playbac
kRate(); | 204 : (document()->animationClock().currentTime() - zeroTime()) * m_playback
Rate; |
205 isNull = std::isnan(result); | 205 isNull = std::isnan(result); |
206 return result; | 206 return result; |
207 } | 207 } |
208 | 208 |
209 double AnimationTimeline::currentTime() | 209 double AnimationTimeline::currentTime() |
210 { | 210 { |
211 return currentTimeInternal() * 1000; | 211 return currentTimeInternal() * 1000; |
212 } | 212 } |
213 | 213 |
214 double AnimationTimeline::currentTimeInternal() | 214 double AnimationTimeline::currentTimeInternal() |
215 { | 215 { |
216 bool isNull; | 216 bool isNull; |
217 return currentTimeInternal(isNull); | 217 return currentTimeInternal(isNull); |
218 } | 218 } |
219 | 219 |
220 void AnimationTimeline::setCurrentTime(double currentTime) | 220 void AnimationTimeline::setCurrentTime(double currentTime) |
221 { | 221 { |
222 setCurrentTimeInternal(currentTime / 1000); | 222 setCurrentTimeInternal(currentTime / 1000); |
223 } | 223 } |
224 | 224 |
225 void AnimationTimeline::setCurrentTimeInternal(double currentTime) | 225 void AnimationTimeline::setCurrentTimeInternal(double currentTime) |
226 { | 226 { |
227 m_zeroTimeOffset = document()->animationClock().currentTime() - m_zeroTime -
currentTime; | 227 m_zeroTime = m_playbackRate == 0 |
| 228 ? currentTime |
| 229 : (document()->animationClock().currentTime() - currentTime) / m_playbac
kRate; |
| 230 m_zeroTimeInitialized = true; |
| 231 |
| 232 for (const auto& player : m_players) { |
| 233 // The Player needs a timing update to pick up a new time. |
| 234 player->setOutdated(); |
| 235 // Any corresponding compositor animation will need to be restarted. Mar
king the |
| 236 // source changed forces this. |
| 237 player->setCompositorPending(true); |
| 238 } |
228 } | 239 } |
229 | 240 |
230 double AnimationTimeline::effectiveTime() | 241 double AnimationTimeline::effectiveTime() |
231 { | 242 { |
232 double time = currentTimeInternal(); | 243 double time = currentTimeInternal(); |
233 return std::isnan(time) ? 0 : time; | 244 return std::isnan(time) ? 0 : time; |
234 } | 245 } |
235 | 246 |
236 void AnimationTimeline::pauseAnimationsForTesting(double pauseTime) | 247 void AnimationTimeline::pauseAnimationsForTesting(double pauseTime) |
237 { | 248 { |
(...skipping 19 matching lines...) Expand all Loading... |
257 void AnimationTimeline::setOutdatedAnimationPlayer(AnimationPlayer* player) | 268 void AnimationTimeline::setOutdatedAnimationPlayer(AnimationPlayer* player) |
258 { | 269 { |
259 ASSERT(player->outdated()); | 270 ASSERT(player->outdated()); |
260 m_playersNeedingUpdate.add(player); | 271 m_playersNeedingUpdate.add(player); |
261 if (m_document && m_document->page() && !m_document->page()->animator().isSe
rvicingAnimations()) | 272 if (m_document && m_document->page() && !m_document->page()->animator().isSe
rvicingAnimations()) |
262 m_timing->serviceOnNextFrame(); | 273 m_timing->serviceOnNextFrame(); |
263 } | 274 } |
264 | 275 |
265 void AnimationTimeline::setPlaybackRate(double playbackRate) | 276 void AnimationTimeline::setPlaybackRate(double playbackRate) |
266 { | 277 { |
267 // FIXME: floating point error difference between current time before and af
ter the playback rate changes | 278 double currentTime = currentTimeInternal(); |
268 if (!m_documentCurrentTimeSnapshot) | |
269 m_documentCurrentTimeSnapshot = m_zeroTime; | |
270 m_zeroTimeOffset += (document()->animationClock().currentTime() - m_document
CurrentTimeSnapshot) * (1 - m_playbackRate); | |
271 m_documentCurrentTimeSnapshot = document()->animationClock().currentTime(); | |
272 m_playbackRate = playbackRate; | 279 m_playbackRate = playbackRate; |
| 280 m_zeroTime = playbackRate == 0 |
| 281 ? currentTime |
| 282 : document()->animationClock().currentTime() - currentTime / playbackRat
e; |
| 283 m_zeroTimeInitialized = true; |
| 284 |
273 for (const auto& player : m_players) { | 285 for (const auto& player : m_players) { |
| 286 // Corresponding compositor animation may need to be restarted to pick u
p |
| 287 // the new playback rate. Marking the source changed forces this. |
274 player->setCompositorPending(true); | 288 player->setCompositorPending(true); |
275 } | 289 } |
276 } | 290 } |
277 | 291 |
278 double AnimationTimeline::playbackRate() const | 292 double AnimationTimeline::playbackRate() const |
279 { | 293 { |
280 return m_playbackRate; | 294 return m_playbackRate; |
281 } | 295 } |
282 | 296 |
283 #if !ENABLE(OILPAN) | 297 #if !ENABLE(OILPAN) |
284 void AnimationTimeline::detachFromDocument() | 298 void AnimationTimeline::detachFromDocument() |
285 { | 299 { |
286 // FIXME: AnimationTimeline should keep Document alive. | 300 // FIXME: AnimationTimeline should keep Document alive. |
287 m_document = nullptr; | 301 m_document = nullptr; |
288 } | 302 } |
289 #endif | 303 #endif |
290 | 304 |
291 void AnimationTimeline::trace(Visitor* visitor) | 305 void AnimationTimeline::trace(Visitor* visitor) |
292 { | 306 { |
293 #if ENABLE(OILPAN) | 307 #if ENABLE(OILPAN) |
294 visitor->trace(m_document); | 308 visitor->trace(m_document); |
295 visitor->trace(m_timing); | 309 visitor->trace(m_timing); |
296 visitor->trace(m_playersNeedingUpdate); | 310 visitor->trace(m_playersNeedingUpdate); |
297 visitor->trace(m_players); | 311 visitor->trace(m_players); |
298 #endif | 312 #endif |
299 } | 313 } |
300 | 314 |
301 } // namespace | 315 } // namespace |
OLD | NEW |