void Animation::setCompositorPending(bool effectChanged) { // FIXME: KeyframeEffect could notify this directly? if (!hasActiveAnimationsOnCompositor()) { destroyCompositorPlayer(); m_compositorState.release(); } if (effectChanged && m_compositorState) { m_compositorState->effectChanged = true; } if (m_compositorPending || m_isPausedForTesting) { return; } #if !ENABLE(OILPAN) if (!timeline() || !timeline()->document()) { return; } #endif if (!m_compositorState || m_compositorState->effectChanged || m_compositorState->playbackRate != m_playbackRate || m_compositorState->startTime != m_startTime) { m_compositorPending = true; timeline()->document()->compositorPendingAnimations().add(this); } }
double Animation::timeToEffectChange() { ASSERT(!m_outdated); if (!hasStartTime()) return std::numeric_limits<double>::infinity(); double currentTime = calculateCurrentTime(); if (m_held) { if (limited(currentTime)) { if (m_playbackRate > 0 && m_endClip + effectEnd() > currentTime) return m_endClip + effectEnd() - currentTime; if (m_playbackRate < 0 && m_startClip <= currentTime) return m_startClip - currentTime; } return std::numeric_limits<double>::infinity(); } if (!m_content) return -currentTimeInternal() / m_playbackRate; double result = m_playbackRate > 0 ? m_content->timeToForwardsEffectChange() / m_playbackRate : m_content->timeToReverseEffectChange() / -m_playbackRate; return !hasActiveAnimationsOnCompositor() && m_content->phase() == AnimationEffect::PhaseActive ? 0 : clipTimeToEffectChange(result); }
void Animation::cancelAnimationOnCompositor() { if (hasActiveAnimationsOnCompositor()) toKeyframeEffect(m_content.get())->cancelAnimationOnCompositor(); destroyCompositorPlayer(); }
void Player::pauseForTesting() { RELEASE_ASSERT(!paused()); if (!m_isPausedForTesting && hasActiveAnimationsOnCompositor()) toAnimation(m_content.get())->pauseAnimationForTestingOnCompositor(currentTime()); m_isPausedForTesting = true; setPausedImpl(true); }
void Animation::pauseAnimationForTestingOnCompositor(double pauseTime) { ASSERT(hasActiveAnimationsOnCompositor()); if (!m_target || !m_target->renderer()) return; for (const auto& compositorAnimationId : m_compositorAnimationIds) CompositorAnimations::instance()->pauseAnimationForTestingOnCompositor(*m_target, compositorAnimationId, pauseTime); }
void Animation::pauseAnimationForTestingOnCompositor(double pauseTime) { ASSERT(hasActiveAnimationsOnCompositor()); if (!m_target || !m_target->renderer()) return; for (size_t i = 0; i < m_compositorAnimationIds.size(); ++i) CompositorAnimations::instance()->pauseAnimationForTestingOnCompositor(*m_target, m_compositorAnimationIds[i], pauseTime); }
void AnimationPlayer::pauseForTesting(double pauseTime) { RELEASE_ASSERT(!paused()); setCurrentTimeInternal(pauseTime, TimingUpdateOnDemand); if (hasActiveAnimationsOnCompositor()) toAnimation(m_content.get())->pauseAnimationForTestingOnCompositor(currentTimeInternal()); m_isPausedForTesting = true; pause(); }
void KeyframeEffect::pauseAnimationForTestingOnCompositor(double pauseTime) { ASSERT(hasActiveAnimationsOnCompositor()); if (!m_target || !m_target->layoutObject()) return; ASSERT(animation()); for (const auto& compositorAnimationId : m_compositorAnimationIds) CompositorAnimations::instance()->pauseAnimationForTestingOnCompositor(*m_target, *animation(), compositorAnimationId, pauseTime); }
void AnimationPlayer::pauseForTesting(double pauseTime) { RELEASE_ASSERT(!paused()); updateTimingState(pauseTime); if (!m_isPausedForTesting && hasActiveAnimationsOnCompositor()) toAnimation(m_content.get())->pauseAnimationForTestingOnCompositor(currentTime()); m_isPausedForTesting = true; pause(); }
void Animation::cancelAnimationOnCompositor() { if (!hasActiveAnimationsOnCompositor()) return; if (!m_target || !m_target->renderer()) return; for (size_t i = 0; i < m_compositorAnimationIds.size(); ++i) CompositorAnimations::instance()->cancelAnimationOnCompositor(*m_target.get(), m_compositorAnimationIds[i]); m_compositorAnimationIds.clear(); }
void KeyframeEffectReadOnly::pauseAnimationForTestingOnCompositor( double pauseTime) { DCHECK(hasActiveAnimationsOnCompositor()); if (!m_target || !m_target->layoutObject()) return; DCHECK(animation()); for (const auto& compositorAnimationId : m_compositorAnimationIds) { CompositorAnimations::pauseAnimationForTestingOnCompositor( *m_target, *animation(), compositorAnimationId, pauseTime); } }
void Player::setCurrentTime(double seekTime) { if (pausedInternal()) m_pauseStartTime = seekTime; else m_timeDrift = currentTimeBeforeDrift() - seekTime; if (m_isPausedForTesting && hasActiveAnimationsOnCompositor()) toAnimation(m_content.get())->pauseAnimationForTestingOnCompositor(currentTime()); update(); }
bool KeyframeEffect::maybeStartAnimationOnCompositor(int group, double startTime, double currentTime, double animationPlaybackRate) { ASSERT(!hasActiveAnimationsOnCompositor()); if (!isCandidateForAnimationOnCompositor(animationPlaybackRate)) return false; if (!CompositorAnimations::instance()->canStartAnimationOnCompositor(*m_target)) return false; if (!CompositorAnimations::instance()->startAnimationOnCompositor(*m_target, group, startTime, currentTime, specifiedTiming(), *animation(), *model(), m_compositorAnimationIds, animationPlaybackRate)) return false; ASSERT(!m_compositorAnimationIds.isEmpty()); return true; }
bool Animation::maybeStartAnimationOnCompositor(double startTime, double currentTime) { ASSERT(!hasActiveAnimationsOnCompositor()); if (!isCandidateForAnimationOnCompositor()) return false; if (!CompositorAnimations::instance()->canStartAnimationOnCompositor(*m_target)) return false; if (!CompositorAnimations::instance()->startAnimationOnCompositor(*m_target, startTime, currentTime, specifiedTiming(), *effect(), m_compositorAnimationIds)) return false; ASSERT(!m_compositorAnimationIds.isEmpty()); return true; }
bool Animation::maybeStartAnimationOnCompositor() { ASSERT(!hasActiveAnimationsOnCompositor()); if (!isCandidateForAnimationOnCompositor()) return false; if (!CompositorAnimations::instance()->canStartAnimationOnCompositor(*m_target.get())) return false; if (!CompositorAnimations::instance()->startAnimationOnCompositor(*m_target.get(), specified(), *effect(), m_compositorAnimationIds)) return false; ASSERT(!m_compositorAnimationIds.isEmpty()); return true; }
void AnimationPlayer::setCompositorPending(bool sourceChanged) { // FIXME: Animation could notify this directly? if (!hasActiveAnimationsOnCompositor()) { m_compositorState.release(); } if (!m_compositorPending) { m_compositorPending = true; if (sourceChanged && m_compositorState) m_compositorState->sourceChanged = true; timeline()->document()->compositorPendingAnimations().add(this); } }
void Animation::cancelAnimationOnCompositor() { // FIXME: cancelAnimationOnCompositor is called from withins style recalc. // This queries compositingState, which is not necessarily up to date. // https://code.google.com/p/chromium/issues/detail?id=339847 DisableCompositingQueryAsserts disabler; if (!hasActiveAnimationsOnCompositor()) return; if (!m_target || !m_target->renderer()) return; for (size_t i = 0; i < m_compositorAnimationIds.size(); ++i) CompositorAnimations::instance()->cancelAnimationOnCompositor(*m_target, m_compositorAnimationIds[i]); m_compositorAnimationIds.clear(); }
double AnimationPlayer::timeToEffectChange() { ASSERT(!m_outdated); if (m_held || !hasStartTime()) return std::numeric_limits<double>::infinity(); if (!m_content) return -currentTimeInternal() / m_playbackRate; double result = m_playbackRate > 0 ? m_content->timeToForwardsEffectChange() / m_playbackRate : m_content->timeToReverseEffectChange() / -m_playbackRate; return !hasActiveAnimationsOnCompositor() && m_content->phase() == AnimationNode::PhaseActive ? 0 : result; }
bool KeyframeEffect::cancelAnimationOnCompositor() { // FIXME: cancelAnimationOnCompositor is called from withins style recalc. // This queries compositingState, which is not necessarily up to date. // https://code.google.com/p/chromium/issues/detail?id=339847 DisableCompositingQueryAsserts disabler; if (!hasActiveAnimationsOnCompositor()) return false; if (!m_target || !m_target->layoutObject()) return false; ASSERT(animation()); for (const auto& compositorAnimationId : m_compositorAnimationIds) CompositorAnimations::instance()->cancelAnimationOnCompositor(*m_target, *animation(), compositorAnimationId); m_compositorAnimationIds.clear(); return true; }
void AnimationPlayer::setCompositorPending(bool sourceChanged) { // FIXME: Animation could notify this directly? if (!hasActiveAnimationsOnCompositor()) { m_compositorState.release(); } if (sourceChanged && m_compositorState) { m_compositorState->sourceChanged = true; } if (m_compositorPending || m_isPausedForTesting) { return; } if (sourceChanged || !m_compositorState || !playing() || m_compositorState->playbackRate != m_playbackRate || m_compositorState->startTime != m_startTime) { m_compositorPending = true; timeline()->document()->compositorPendingAnimations().add(this); } }
double Animation::calculateTimeToEffectChange(double localTime, double timeToNextIteration) const { const double activeStartTime = startTime() + specified().startDelay; switch (phase()) { case PhaseBefore: return activeStartTime - localTime; case PhaseActive: if (hasActiveAnimationsOnCompositor()) { // Need service to apply fill / fire events. const double activeEndTime = activeStartTime + activeDuration(); return std::min(activeEndTime - localTime, timeToNextIteration); } return 0; case PhaseAfter: // 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 std::numeric_limits<double>::infinity(); case PhaseNone: default: ASSERT_NOT_REACHED(); return 0; } }
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(); } }
void AnimationPlayer::cancelAnimationOnCompositor() { if (hasActiveAnimationsOnCompositor()) toAnimation(m_content.get())->cancelAnimationOnCompositor(); }
void Animation::restartAnimationOnCompositor() { if (hasActiveAnimationsOnCompositor()) toKeyframeEffect(m_content.get())->restartAnimationOnCompositor(); }
bool Animation::hasActiveAnimationsOnCompositor(CSSPropertyID property) const { return hasActiveAnimationsOnCompositor() && affects(property); }
bool KeyframeEffectReadOnly::hasActiveAnimationsOnCompositor( CSSPropertyID property) const { return hasActiveAnimationsOnCompositor() && affects(PropertyHandle(property)); }