double Animation::calculateTimeToEffectChange(bool forwards, double localTime, double timeToNextIteration) const { const double start = startTimeInternal() + specifiedTiming().startDelay; const double end = start + activeDurationInternal(); switch (phase()) { case PhaseBefore: ASSERT(start >= localTime); return forwards ? start - localTime : std::numeric_limits<double>::infinity(); case PhaseActive: return 0; case PhaseAfter: ASSERT(localTime >= end); // If this Animation is still in effect then it will need to update // when its parent goes out of effect. We have no way of knowing when // that will be, however, so the parent will need to supply it. return forwards ? std::numeric_limits<double>::infinity() : localTime - end; default: ASSERT_NOT_REACHED(); return std::numeric_limits<double>::infinity(); } }
bool AnimationPlayer::maybeStartAnimationOnCompositor() { if (!canStartAnimationOnCompositor()) return false; double startTime = timeline()->zeroTime() + startTimeInternal(); double timeOffset = 0; if (std::isnan(startTime)) { timeOffset = currentTimeInternal(); } return toAnimation(m_content.get())->maybeStartAnimationOnCompositor(startTime, timeOffset); }
bool AnimationPlayer::maybeStartAnimationOnCompositor() { if (!canStartAnimationOnCompositor()) return false; bool reversed = m_playbackRate < 0; double startTime = timeline()->zeroTime() + startTimeInternal(); if (reversed) { startTime -= sourceEnd() / fabs(m_playbackRate); } double timeOffset = 0; if (std::isnan(startTime)) { timeOffset = reversed ? sourceEnd() - currentTimeInternal() : currentTimeInternal(); timeOffset = timeOffset / fabs(m_playbackRate); } ASSERT(m_compositorGroup != 0); return toAnimation(m_content.get())->maybeStartAnimationOnCompositor(m_compositorGroup, startTime, timeOffset, m_playbackRate); }
double Animation::calculateTimeToEffectChange(bool forwards, double localTime, double timeToNextIteration) const { const double start = startTimeInternal() + specifiedTiming().startDelay; const double end = start + activeDurationInternal(); switch (phase()) { case PhaseBefore: ASSERT(start >= localTime); return forwards ? start - localTime : std::numeric_limits<double>::infinity(); case PhaseActive: if (forwards && hasActiveAnimationsOnCompositor()) { ASSERT(specifiedTiming().playbackRate == 1); // Need service to apply fill / fire events. const double timeToEnd = end - localTime; if (hasEvents()) { return std::min(timeToEnd, timeToNextIteration); } else { return timeToEnd; } } return 0; case PhaseAfter: ASSERT(localTime >= end); // If this Animation is still in effect then it will need to update // when its parent goes out of effect. We have no way of knowing when // that will be, however, so the parent will need to supply it. return forwards ? std::numeric_limits<double>::infinity() : localTime - end; default: ASSERT_NOT_REACHED(); return std::numeric_limits<double>::infinity(); } }