Exemple #1
0
void AnimationPlayer::notifyCompositorStartTime(double timelineTime)
{
    if (m_compositorState) {
        ASSERT(m_compositorState->pendingAction == Start);
        ASSERT(std::isnan(m_compositorState->startTime));

        double initialCompositorHoldTime = m_compositorState->holdTime;
        m_compositorState->pendingAction = None;
        m_compositorState->startTime = timelineTime;

        if (paused() || m_compositorState->playbackRate != m_playbackRate || m_compositorState->sourceChanged) {
            // Paused state, playback rate, or source changed while starting.
            setCompositorPending();
        }

        if (m_startTime == timelineTime) {
            // The start time was set to the incoming compositor start time.
            // Unlikely, but possible.
            // FIXME: Depending on what changed above this might still be pending.
            // Maybe...
            m_currentTimePending = false;
            return;
        }

        if (!std::isnan(m_startTime) || currentTimeInternal() != initialCompositorHoldTime) {
            // A new start time or current time was set while starting.
            setCompositorPending();
            return;
        }
    }

    if (playing()) {
        ASSERT(std::isnan(m_startTime));
        ASSERT(m_held);

        if (m_playbackRate == 0) {
            setStartTimeInternal(timelineTime);
        } else {
            setStartTimeInternal(timelineTime + currentTimeInternal() / -m_playbackRate);
        }

        // FIXME: This avoids marking this player as outdated needlessly when a start time
        // is notified, but we should refactor how outdating works to avoid this.
        m_outdated = false;

        m_currentTimePending = false;
    }
}
Exemple #2
0
void AnimationPlayer::notifyCompositorStartTime(double timelineTime)
{
    PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand, DoNotSetCompositorPending);

    if (m_compositorState) {
        ASSERT(m_compositorState->pendingAction == Start);
        ASSERT(std::isnan(m_compositorState->startTime));

        double initialCompositorHoldTime = m_compositorState->holdTime;
        m_compositorState->pendingAction = None;
        m_compositorState->startTime = timelineTime + currentTimeInternal() / -m_playbackRate;

        if (m_startTime == timelineTime) {
            // The start time was set to the incoming compositor start time.
            // Unlikely, but possible.
            // FIXME: Depending on what changed above this might still be pending.
            // Maybe...
            m_currentTimePending = false;
            return;
        }

        if (!std::isnan(m_startTime) || currentTimeInternal() != initialCompositorHoldTime) {
            // A new start time or current time was set while starting.
            setCompositorPending(true);
            return;
        }
    }

    notifyStartTime(timelineTime);
}
Exemple #3
0
void AnimationPlayer::unpause()
{
    if (!m_paused)
        return;
    setCompositorPending();
    m_currentTimePending = true;
    unpauseInternal();
}
Exemple #4
0
void AnimationPlayer::pause()
{
    if (m_paused)
        return;
    if (playing()) {
        setCompositorPending();
        m_currentTimePending = true;
    }
    m_paused = true;
    setCurrentTimeInternal(currentTimeInternal(), TimingUpdateOnDemand);
}
Exemple #5
0
void AnimationPlayer::setStartTime(double startTime)
{
    if (m_paused) // FIXME: Should this throw an exception?
        return;
    if (!std::isfinite(startTime))
        return;
    if (startTime == m_startTime)
        return;

    setCompositorPending();
    m_currentTimePending = false;
    setStartTimeInternal(startTime / 1000);
}
Exemple #6
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 #7
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 #8
0
void AnimationPlayer::setPlaybackRate(double playbackRate)
{
    if (!std::isfinite(playbackRate))
        return;
    if (playbackRate == m_playbackRate)
        return;

    setCompositorPending();
    if (!finished() && !paused())
        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 #9
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());
}
Exemple #10
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);
}