Exemple #1
0
void AnimationPlayer::play()
{
    PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand);

    if (!playing())
        m_startTime = nullValue();

    if (playStateInternal() == Idle) {
        // We may not go into the pending state, but setting it to something other
        // than Idle here will force an update.
        ASSERT(isNull(m_startTime));
        m_playState = Pending;
        m_held = true;
        m_holdTime = 0;
    }

    m_finished = false;
    unpauseInternal();
    if (!m_content)
        return;
    double currentTime = this->currentTimeInternal();
    if (m_playbackRate > 0 && (currentTime < 0 || currentTime >= sourceEnd()))
        setCurrentTimeInternal(0, TimingUpdateOnDemand);
    else if (m_playbackRate < 0 && (currentTime <= 0 || currentTime > sourceEnd()))
        setCurrentTimeInternal(sourceEnd(), TimingUpdateOnDemand);
}
Exemple #2
0
void AnimationPlayer::play()
{
    if (!playing())
        m_startTime = nullValue();

    setCompositorPending();
    unpauseInternal();
    if (!m_content)
        return;
    double currentTime = this->currentTimeInternal();
    if (m_playbackRate > 0 && (currentTime < 0 || currentTime >= sourceEnd()))
        setCurrentTimeInternal(0, TimingUpdateOnDemand);
    else if (m_playbackRate < 0 && (currentTime <= 0 || currentTime > sourceEnd()))
        setCurrentTimeInternal(sourceEnd(), TimingUpdateOnDemand);
    m_finished = false;
}
Exemple #3
0
void AnimationPlayer::postCommit(double timelineTime)
{
    PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand, DoNotSetCompositorPending);

    m_compositorPending = false;

    if (!m_compositorState || m_compositorState->pendingAction == None)
        return;

    switch (m_compositorState->pendingAction) {
    case Start:
        if (!std::isnan(m_compositorState->startTime)) {
            ASSERT(m_startTime == m_compositorState->startTime);
            m_compositorState->pendingAction = None;
        }
        break;
    case Pause:
    case PauseThenStart:
        ASSERT(std::isnan(m_startTime));
        m_compositorState->pendingAction = None;
        setCurrentTimeInternal((timelineTime - m_compositorState->startTime) * m_playbackRate, TimingUpdateForAnimationFrame);
        m_currentTimePending = false;
        break;
    default:
        ASSERT_NOT_REACHED();
    }
}
Exemple #4
0
void AnimationPlayer::setStartTimeInternal(double newStartTime)
{
    ASSERT(!m_paused);
    ASSERT(std::isfinite(newStartTime));
    ASSERT(newStartTime != m_startTime);

    bool hadStartTime = hasStartTime();
    double previousCurrentTime = currentTimeInternal();
    m_startTime = newStartTime;
    if (m_held && m_playbackRate) {
        // If held, the start time would still be derrived from the hold time.
        // Force a new, limited, current time.
        m_held = false;
        double currentTime = calculateCurrentTime();
        if (m_playbackRate > 0 && currentTime > sourceEnd()) {
            currentTime = sourceEnd();
        } else if (m_playbackRate < 0 && currentTime < 0) {
            currentTime = 0;
        }
        setCurrentTimeInternal(currentTime, TimingUpdateOnDemand);
    }
    updateCurrentTimingState(TimingUpdateOnDemand);
    double newCurrentTime = currentTimeInternal();

    if (previousCurrentTime != newCurrentTime) {
        setOutdated();
    } else if (!hadStartTime && m_timeline) {
        // Even though this player is not outdated, time to effect change is
        // infinity until start time is set.
        m_timeline->wake();
    }
}
Exemple #5
0
void AnimationPlayer::unpauseInternal()
{
    if (!m_paused)
        return;
    m_paused = false;
    setCurrentTimeInternal(currentTimeInternal(), TimingUpdateOnDemand);
}
Exemple #6
0
void AnimationPlayer::reverse()
{
    if (!m_playbackRate) {
        return;
    }
    if (m_content) {
        if (m_playbackRate > 0 && currentTimeInternal() > sourceEnd()) {
            setCurrentTimeInternal(sourceEnd(), TimingUpdateOnDemand);
            ASSERT(finished());
        } else if (m_playbackRate < 0 && currentTimeInternal() < 0) {
            setCurrentTimeInternal(0, TimingUpdateOnDemand);
            ASSERT(finished());
        }
    }
    setPlaybackRate(-m_playbackRate);
    unpauseInternal();
}
Exemple #7
0
void AnimationPlayer::pauseForTesting(double pauseTime)
{
    RELEASE_ASSERT(!paused());
    setCurrentTimeInternal(pauseTime, TimingUpdateOnDemand);
    if (hasActiveAnimationsOnCompositor())
        toAnimation(m_content.get())->pauseAnimationForTestingOnCompositor(currentTimeInternal());
    m_isPausedForTesting = true;
    pause();
}
Exemple #8
0
void AnimationPlayer::finish(ExceptionState& exceptionState)
{
    if (!m_playbackRate) {
        return;
    }
    if (m_playbackRate > 0 && sourceEnd() == std::numeric_limits<double>::infinity()) {
        exceptionState.throwDOMException(InvalidStateError, "AnimationPlayer has source content whose end time is infinity.");
        return;
    }
    if (playing()) {
        setCompositorPending();
    }
    if (m_playbackRate < 0) {
        setCurrentTimeInternal(0, TimingUpdateOnDemand);
    } else {
        setCurrentTimeInternal(sourceEnd(), TimingUpdateOnDemand);
    }
    ASSERT(finished());
}
void Animation::setCurrentTime(double newCurrentTime)
{
    PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand);

    m_currentTimePending = false;
    setCurrentTimeInternal(newCurrentTime / 1000, TimingUpdateOnDemand);

    if (calculatePlayState() == Finished)
        m_startTime = calculateStartTime(newCurrentTime);
}
Exemple #10
0
void AnimationPlayer::pause()
{
    if (m_paused)
        return;
    if (playing()) {
        setCompositorPending();
        m_currentTimePending = true;
    }
    m_paused = true;
    setCurrentTimeInternal(currentTimeInternal(), TimingUpdateOnDemand);
}
Exemple #11
0
void AnimationPlayer::setCurrentTime(double newCurrentTime)
{
    UseCounter::count(executionContext(), UseCounter::AnimationPlayerSetCurrentTime);
    if (!std::isfinite(newCurrentTime))
        return;

    PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand);

    m_currentTimePending = false;
    setCurrentTimeInternal(newCurrentTime / 1000, TimingUpdateOnDemand);
}
Exemple #12
0
// Update timing to reflect updated animation clock due to tick
void AnimationPlayer::updateCurrentTimingState(TimingUpdateReason reason)
{
    if (m_held) {
        setCurrentTimeInternal(m_holdTime, reason);
        return;
    }
    if (!limited(calculateCurrentTime()))
        return;
    m_held = true;
    m_holdTime = m_playbackRate < 0 ? 0 : sourceEnd();
}
Exemple #13
0
void AnimationPlayer::pause()
{
    if (m_paused)
        return;

    PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand);

    if (playing()) {
        m_currentTimePending = true;
    }
    m_paused = true;
    setCurrentTimeInternal(currentTimeInternal(), TimingUpdateOnDemand);
}
Exemple #14
0
void AnimationPlayer::setCurrentTime(double newCurrentTime)
{
    if (!std::isfinite(newCurrentTime))
        return;

    setCompositorPending();

    // Setting current time while pending forces a start time.
    if (m_currentTimePending) {
        m_startTime = 0;
        m_currentTimePending = false;
    }

    setCurrentTimeInternal(newCurrentTime / 1000, TimingUpdateOnDemand);
}
Exemple #15
0
void AnimationPlayer::setPlaybackRateInternal(double playbackRate)
{
    ASSERT(std::isfinite(playbackRate));
    ASSERT(playbackRate != m_playbackRate);

    if (!finished() && !paused() && hasStartTime())
        m_currentTimePending = true;

    double storedCurrentTime = currentTimeInternal();
    if ((m_playbackRate < 0 && playbackRate >= 0) || (m_playbackRate > 0 && playbackRate <= 0))
        m_finished = false;

    m_playbackRate = playbackRate;
    m_startTime = std::numeric_limits<double>::quiet_NaN();
    setCurrentTimeInternal(storedCurrentTime, TimingUpdateOnDemand);
}
Exemple #16
0
void AnimationPlayer::setSource(AnimationNode* newSource)
{
    if (m_content == newSource)
        return;

    setCompositorPending(true);

    double storedCurrentTime = currentTimeInternal();
    if (m_content)
        m_content->detach();
    m_content = newSource;
    if (newSource) {
        // FIXME: This logic needs to be updated once groups are implemented
        if (newSource->player())
            newSource->player()->cancel();
        newSource->attach(this);
        setOutdated();
    }
    setCurrentTimeInternal(storedCurrentTime, TimingUpdateOnDemand);
}
Exemple #17
0
void AnimationPlayer::finish(ExceptionState& exceptionState)
{
    PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand);

    if (!m_playbackRate || playStateInternal() == Idle) {
        return;
    }
    if (m_playbackRate > 0 && sourceEnd() == std::numeric_limits<double>::infinity()) {
        exceptionState.throwDOMException(InvalidStateError, "AnimationPlayer has source content whose end time is infinity.");
        return;
    }

    double newCurrentTime = m_playbackRate < 0 ? 0 : sourceEnd();
    setCurrentTimeInternal(newCurrentTime, TimingUpdateOnDemand);
    if (!paused()) {
        m_startTime = calculateStartTime(newCurrentTime);
    }

    m_currentTimePending = false;
    ASSERT(finished());
}
void Animation::setEffect(AnimationEffect* newEffect)
{
    if (m_content == newEffect)
        return;
    PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand, SetCompositorPendingWithEffectChanged);

    double storedCurrentTime = currentTimeInternal();
    if (m_content)
        m_content->detach();
    m_content = newEffect;
    if (newEffect) {
        // FIXME: This logic needs to be updated once groups are implemented
        if (newEffect->animation()) {
            newEffect->animation()->cancel();
            newEffect->animation()->setEffect(0);
        }
        newEffect->attach(this);
        setOutdated();
    }
    setCurrentTimeInternal(storedCurrentTime, TimingUpdateOnDemand);
}
// Update timing to reflect updated animation clock due to tick
void Animation::updateCurrentTimingState(TimingUpdateReason reason)
{
    if (m_held) {
        double newCurrentTime = m_holdTime;
        if (playStateInternal() == Finished && !isNull(m_startTime) && m_timeline) {
            // Add hystersis due to floating point error accumulation
            if (!limited(calculateCurrentTime() + 0.001 * m_playbackRate)) {
                // The current time became unlimited, eg. due to a backwards
                // seek of the timeline.
                newCurrentTime = calculateCurrentTime();
            } else if (!limited(m_holdTime)) {
                // The hold time became unlimited, eg. due to the effect
                // becoming longer.
                newCurrentTime = clampTo<double>(calculateCurrentTime(), 0, effectEnd());
            }
        }
        setCurrentTimeInternal(newCurrentTime, reason);
    } else if (limited(calculateCurrentTime())) {
        m_held = true;
        m_holdTime = m_playbackRate < 0 ? 0 : effectEnd();
    }
}
void AnimationTimeline::setCurrentTime(double currentTime)
{
    setCurrentTimeInternal(currentTime / 1000);
}