void ScrollAnimatorNone::animationTimerFired()
{
    TRACE_EVENT0("webkit", "ScrollAnimatorNone::animationTimerFired");

    double currentTime = WTF::monotonicallyIncreasingTime();
    double deltaToNextFrame = ceil((currentTime - m_startTime) * kFrameRate) / kFrameRate - (currentTime - m_startTime);
    currentTime += deltaToNextFrame;

    bool continueAnimation = false;
    if (m_horizontalData.m_startTime && m_horizontalData.animateScroll(currentTime))
        continueAnimation = true;
    if (m_verticalData.m_startTime && m_verticalData.animateScroll(currentTime))
        continueAnimation = true;

    if (continueAnimation)
        startNextTimer();
    else
        m_animationActive = false;

    TRACE_EVENT0("webkit", "ScrollAnimatorNone::notifyPositionChanged");
    notifyPositionChanged(FloatSize());

    if (!continueAnimation)
        animationDidFinish();
}
Beispiel #2
0
void ScrollAnimatorNone::animationTimerFired()
{
#if PLATFORM(CHROMIUM)
    TRACE_EVENT("ScrollAnimatorNone::animationTimerFired", this, 0);
#endif

    double currentTime = WTF::monotonicallyIncreasingTime();
    double deltaToNextFrame = ceil((currentTime - m_startTime) * kFrameRate) / kFrameRate - (currentTime - m_startTime);
    currentTime += deltaToNextFrame;

    bool continueAnimation = false;
    if (m_horizontalData.m_startTime && m_horizontalData.animateScroll(currentTime))
        continueAnimation = true;
    if (m_verticalData.m_startTime && m_verticalData.animateScroll(currentTime))
        continueAnimation = true;

    if (m_gestureAnimation) {
        if (m_gestureAnimation->animate(currentTime))
            continueAnimation = true;
        else
            m_gestureAnimation.clear();
    }

    if (continueAnimation)
        startNextTimer();
    else
        m_animationActive = false;

#if PLATFORM(CHROMIUM)
    TRACE_EVENT("ScrollAnimatorNone::notifyPositionChanged", this, 0);
#endif
    notifyPositionChanged();
}
void ScrollAnimator::scrollToOffsetWithoutAnimation(const FloatPoint& offset)
{
    FloatSize delta = FloatSize(offset.x() - m_currentPosX, offset.y() - m_currentPosY);
    m_currentPosX = offset.x();
    m_currentPosY = offset.y();
    notifyPositionChanged(delta);
}
void ScrollAnimator::tickAnimation(double monotonicTime)
{
    if (m_runState != RunState::RunningOnMainThread)
        return;

    TRACE_EVENT0("blink", "ScrollAnimator::tickAnimation");
    double elapsedTime = monotonicTime - m_startTime;

    bool isFinished = (elapsedTime > m_animationCurve->duration());
    FloatPoint offset = isFinished ? m_animationCurve->targetValue()
        : m_animationCurve->getValue(elapsedTime);

    offset = FloatPoint(m_scrollableArea->clampScrollPosition(offset));

    m_currentPosX = offset.x();
    m_currentPosY = offset.y();

    if (isFinished)
        resetAnimationState();
    else
        scrollableArea()->scheduleAnimation();

    TRACE_EVENT0("blink", "ScrollAnimator::notifyPositionChanged");
    notifyPositionChanged();
}
void ScrollAnimator::scrollToOffsetWithoutAnimation(const FloatPoint& offset)
{
    m_currentPosX = offset.x();
    m_currentPosY = offset.y();

    resetAnimationState();
    notifyPositionChanged();
}
Beispiel #6
0
void ScrollAnimator::scrollToOffsetWithoutAnimation(const FloatPoint& offset)
{
    if (m_currentPosX != offset.x() || m_currentPosY != offset.y()) {
        m_currentPosX = offset.x();
        m_currentPosY = offset.y();
        notifyPositionChanged();
    }
}
void ProgrammaticScrollAnimator::tickAnimation(double monotonicTime)
{
    if (m_runState != RunState::RunningOnMainThread)
        return;

    if (!m_startTime)
        m_startTime = monotonicTime;
    double elapsedTime = monotonicTime - m_startTime;
    bool isFinished = (elapsedTime > m_animationCurve->duration());
    FloatPoint offset = m_animationCurve->getValue(elapsedTime);
    notifyPositionChanged(IntPoint(offset.x(), offset.y()));

    if (isFinished) {
        resetAnimationState();
    } else if (!m_scrollableArea->scheduleAnimation()) {
        notifyPositionChanged(IntPoint(m_targetOffset.x(), m_targetOffset.y()));
        resetAnimationState();
    }
}
Beispiel #8
0
void ScrollAnimator::scrollToOffsetWithoutAnimation(const FloatPoint& offset)
{
    m_currentPosX = offset.x();
    m_currentPosY = offset.y();

    // Must be called after setting the position since canceling the animation resets
    // the desired position to the current.
    cancelAnimations();
    notifyPositionChanged();
}
Beispiel #9
0
bool ScrollAnimator::scroll(ScrollbarOrientation orientation, ScrollGranularity, float step, float multiplier)
{
    float* currentPos = (orientation == HorizontalScrollbar) ? &m_currentPosX : &m_currentPosY;
    float newPos = std::max(std::min(*currentPos + (step * multiplier), static_cast<float>(m_scrollableArea->scrollSize(orientation))), 0.0f);
    if (*currentPos == newPos)
        return false;
    *currentPos = newPos;

    notifyPositionChanged();

    return true;
}
Beispiel #10
0
bool ScrollAnimator::scroll(ScrollbarOrientation orientation, ScrollGranularity, float step, float delta)
{
    float& currentPos = (orientation == HorizontalScrollbar) ? m_currentPosX : m_currentPosY;
    float newPos = clampScrollPosition(orientation, currentPos + step * delta);
    if (currentPos == newPos)
        return false;
    currentPos = newPos;

    notifyPositionChanged();

    return true;
}
Beispiel #11
0
bool ScrollAnimator::scroll(ScrollbarOrientation orientation, ScrollGranularity, float step, float multiplier)
{
    float* currentPos = (orientation == HorizontalScrollbar) ? &m_currentPosX : &m_currentPosY;
    float newPos = m_scrollableArea->clampScrollPosition(orientation, *currentPos + step * multiplier);
    float delta = *currentPos - newPos;
    if (*currentPos == newPos)
        return false;
    *currentPos = newPos;

    notifyPositionChanged(orientation == HorizontalScrollbar ? FloatSize(delta, 0) : FloatSize(0, delta));

    return true;
}
Beispiel #12
0
void ScrollAnimatorNone::scrollToOffsetWithoutAnimation(const FloatPoint& offset)
{
    stopAnimationTimerIfNeeded();

    m_horizontalData.reset();
    *m_horizontalData.m_currentPosition = offset.x();
    m_horizontalData.m_desiredPosition = offset.x();

    m_verticalData.reset();
    *m_verticalData.m_currentPosition = offset.y();
    m_verticalData.m_desiredPosition = offset.y();

    notifyPositionChanged();
}
Beispiel #13
0
void ScrollAnimatorNone::animationTimerFired(Timer<ScrollAnimatorNone>* timer)
{
    double currentTime = WTF::monotonicallyIncreasingTime();
    double deltaToNextFrame = ceil((currentTime - m_startTime) * kFrameRate) / kFrameRate - (currentTime - m_startTime);

    bool continueAnimation = false;
    if (m_horizontalData.m_startTime && m_horizontalData.animateScroll(currentTime + deltaToNextFrame))
        continueAnimation = true;
    if (m_verticalData.m_startTime && m_verticalData.animateScroll(currentTime + deltaToNextFrame))
        continueAnimation = true;
    if (continueAnimation) {
        double nextTimerInterval = max(kMinimumTimerInterval, deltaToNextFrame);
        timer->startOneShot(nextTimerInterval);
    }
    notifyPositionChanged();
}
void ProgrammaticScrollAnimator::animateToOffset(FloatPoint offset)
{
    m_startTime = 0.0;
    m_targetOffset = offset;
    m_animationCurve = adoptPtr(Platform::current()->compositorSupport()->createScrollOffsetAnimationCurve(
                                    m_targetOffset,
                                    WebCompositorAnimationCurve::TimingFunctionTypeEaseInOut,
                                    WebScrollOffsetAnimationCurve::ScrollDurationDeltaBased));

    m_scrollableArea->registerForAnimation();
    if (!m_scrollableArea->scheduleAnimation()) {
        resetAnimationState();
        notifyPositionChanged(IntPoint(offset.x(), offset.y()));
    }
    m_runState = RunState::WaitingToSendToCompositor;
}
void ScrollAnimatorWin::scrollToOffsetWithoutAnimation(const FloatPoint& offset)
{
    stopAnimationTimerIfNeeded(&m_horizontalData);
    stopAnimationTimerIfNeeded(&m_verticalData);

    *m_horizontalData.m_currentPos = offset.x();
    m_horizontalData.m_desiredPos = offset.x();
    m_horizontalData.m_currentVelocity = 0;
    m_horizontalData.m_desiredVelocity = 0;

    *m_verticalData.m_currentPos = offset.y();
    m_verticalData.m_desiredPos = offset.y();
    m_verticalData.m_currentVelocity = 0;
    m_verticalData.m_desiredVelocity = 0;

    notifyPositionChanged();
}
ScrollResult ScrollAnimatorBase::userScroll(ScrollGranularity, const FloatSize& delta)
{
    FloatSize consumedDelta = computeDeltaToConsume(delta);
    FloatPoint newPos = m_currentPos + consumedDelta;
    if (m_currentPos == newPos)
        return ScrollResult(false, false, delta.width(), delta.height());

    m_currentPos = newPos;

    notifyPositionChanged();

    return ScrollResult(
        consumedDelta.width(),
        consumedDelta.height(),
        delta.width() - consumedDelta.width(),
        delta.height() - consumedDelta.height());
}
void ProgrammaticScrollAnimator::updateCompositorAnimations()
{
    if (m_compositorAnimationId && m_runState != RunState::RunningOnCompositor) {
        // If the current run state is WaitingToSendToCompositor but we have a
        // non-zero compositor animation id, there's a currently running
        // compositor animation that needs to be removed here before the new
        // animation is added below.
        ASSERT(m_runState == RunState::WaitingToCancelOnCompositor || m_runState == RunState::WaitingToSendToCompositor);

        removeAnimation();

        m_compositorAnimationId = 0;
        m_compositorAnimationGroupId = 0;
        if (m_runState == RunState::WaitingToCancelOnCompositor) {
            resetAnimationState();
            return;
        }
    }

    if (m_runState == RunState::WaitingToSendToCompositor) {
        bool sentToCompositor = false;

        if (!m_scrollableArea->shouldScrollOnMainThread()) {
            OwnPtr<WebCompositorAnimation> animation = adoptPtr(Platform::current()->compositorSupport()->createAnimation(*m_animationCurve, WebCompositorAnimation::TargetPropertyScrollOffset));

            int animationId = animation->id();
            int animationGroupId = animation->group();

            if (addAnimation(animation.release())) {
                sentToCompositor = true;
                m_runState = RunState::RunningOnCompositor;
                m_compositorAnimationId = animationId;
                m_compositorAnimationGroupId = animationGroupId;
            }
        }

        if (!sentToCompositor) {
            m_runState = RunState::RunningOnMainThread;
            m_animationCurve->setInitialValue(FloatPoint(m_scrollableArea->scrollPosition()));
            if (!m_scrollableArea->scheduleAnimation()) {
                notifyPositionChanged(IntPoint(m_targetOffset.x(), m_targetOffset.y()));
                resetAnimationState();
            }
        }
    }
}
void ProgrammaticScrollAnimator::layerForCompositedScrollingDidChange(WebCompositorAnimationTimeline* timeline)
{
    reattachCompositorPlayerIfNeeded(timeline);

    // If the composited scrolling layer is lost during a composited animation,
    // continue the animation on the main thread.
    if (m_runState == RunState::RunningOnCompositor && !m_scrollableArea->layerForScrolling()) {
        m_runState = RunState::RunningOnMainThread;
        m_compositorAnimationId = 0;
        m_compositorAnimationGroupId = 0;
        m_animationCurve->setInitialValue(FloatPoint(m_scrollableArea->scrollPosition()));
        m_scrollableArea->registerForAnimation();
        if (!m_scrollableArea->scheduleAnimation()) {
            resetAnimationState();
            notifyPositionChanged(IntPoint(m_targetOffset.x(), m_targetOffset.y()));
        }
    }
}
void ScrollAnimatorNone::animationTimerFired(Timer<ScrollAnimatorNone>* timer)
{
#if PLATFORM(CHROMIUM)
    TRACE_EVENT("ScrollAnimatorNone::animationTimerFired", this, 0);
#endif

    double currentTime = WTF::monotonicallyIncreasingTime();
    double deltaToNextFrame = ceil((currentTime - m_startTime) * kFrameRate) / kFrameRate - (currentTime - m_startTime);

    bool continueAnimation = false;
    if (m_horizontalData.m_startTime && m_horizontalData.animateScroll(currentTime + deltaToNextFrame))
        continueAnimation = true;
    if (m_verticalData.m_startTime && m_verticalData.animateScroll(currentTime + deltaToNextFrame))
        continueAnimation = true;

    if (m_zoomData.m_isAnimating) {
#if PLATFORM(CHROMIUM)
        TRACE_EVENT("ScrollAnimatorNone::notifyZoomChanged", this, 0);
#endif
        if (m_zoomData.m_startTime && m_zoomData.animateZoom(currentTime + deltaToNextFrame)) {
            continueAnimation = true;
            notifyZoomChanged(ZoomAnimationContinuing);
        } else {
            notifyZoomChanged(ZoomAnimationFinishing);
            m_zoomData.m_isAnimating = false;
        }
    }

    if (continueAnimation) {
        double nextTimerInterval = max(kMinimumTimerInterval, deltaToNextFrame);
        timer->startOneShot(nextTimerInterval);
    }

#if PLATFORM(CHROMIUM)
    TRACE_EVENT("ScrollAnimatorNone::notifyPositionChanged", this, 0);
#endif
    notifyPositionChanged();
}
Beispiel #20
0
void ScrollAnimator::animationTimerFired()
{
    TRACE_EVENT0("blink", "ScrollAnimator::animationTimerFired");

    double currentTime = WTF::monotonicallyIncreasingTime();

    bool continueAnimation = false;
    if (m_horizontalData.m_startTime && m_horizontalData.animateScroll(currentTime))
        continueAnimation = true;
    if (m_verticalData.m_startTime && m_verticalData.animateScroll(currentTime))
        continueAnimation = true;

    if (continueAnimation)
        startNextTimer();
    else
        m_animationActive = false;

    TRACE_EVENT0("blink", "ScrollAnimator::notifyPositionChanged");
    notifyPositionChanged();

    if (!continueAnimation)
        animationDidFinish();
}
void ScrollAnimatorWin::animateScroll(PerAxisData* data)
{
    // Note on smooth scrolling perf versus non-smooth scrolling perf:
    // The total time to perform a complete scroll is given by
    //   t = t0 + 0.5tA - tD + tS
    // Where
    //   t0 = The time to perform the scroll without smooth scrolling
    //   tA = The acceleration time,
    //        ScrollbarTheme::theme()->autoscrollTimerDelay() (see below)
    //   tD = |animationTimerDelay|
    //   tS = A value less than or equal to the time required to perform a
    //        single scroll increment, i.e. the work done due to calling
    //        client()->valueChanged() (~0 for simple pages, larger for complex
    //        pages).
    //
    // Because tA and tD are fairly small, the total lag (as users perceive it)
    // is negligible for simple pages and roughly tS for complex pages.  Without
    // knowing in advance how large tS is it's hard to do better than this.
    // Perhaps we could try to remember previous values and forward-compensate.


    // We want to update the scroll position based on the time it's been since
    // our last update.  This may be longer than our ideal time, especially if
    // the page is complex or the system is slow.
    //
    // To avoid feeling laggy, if we've just started smooth scrolling we pretend
    // we've already accelerated for one ideal interval, so that we'll scroll at
    // least some distance immediately.
    double lastScrollInterval = data->m_currentVelocity ? (WTF::currentTime() - data->m_lastAnimationTime) : animationTimerDelay;

    // Figure out how far we've actually traveled and update our current
    // velocity.
    float distanceTraveled;
    if (data->m_currentVelocity < data->m_desiredVelocity) {
        // We accelerate at a constant rate until we reach the desired velocity.
        float accelerationRate = data->m_desiredVelocity / accelerationTime();

        // Figure out whether contant acceleration has caused us to reach our
        // target velocity.
        float potentialVelocityChange = accelerationRate * lastScrollInterval;
        float potentialNewVelocity = data->m_currentVelocity + potentialVelocityChange;
        if (potentialNewVelocity > data->m_desiredVelocity) {
            // We reached the target velocity at some point between our last
            // update and now.  The distance traveled can be calculated in two
            // pieces: the distance traveled while accelerating, and the
            // distance traveled after reaching the target velocity.
            float actualVelocityChange = data->m_desiredVelocity - data->m_currentVelocity;
            float accelerationInterval = actualVelocityChange / accelerationRate;
            // The distance traveled under constant acceleration is the area
            // under a line segment with a constant rising slope.  Break this
            // into a triangular portion atop a rectangular portion and sum.
            distanceTraveled = ((data->m_currentVelocity + (actualVelocityChange / 2)) * accelerationInterval);
            // The distance traveled at the target velocity is simply
            // (target velocity) * (remaining time after accelerating).
            distanceTraveled += (data->m_desiredVelocity * (lastScrollInterval - accelerationInterval));
            data->m_currentVelocity = data->m_desiredVelocity;
        } else {
            // Constant acceleration through the entire time interval.
            distanceTraveled = (data->m_currentVelocity + (potentialVelocityChange / 2)) * lastScrollInterval;
            data->m_currentVelocity = potentialNewVelocity;
        }
    } else {
        // We've already reached the target velocity, so the distance we've
        // traveled is simply (current velocity) * (elapsed time).
        distanceTraveled = data->m_currentVelocity * lastScrollInterval;
        // If our desired velocity has decreased, drop the current velocity too.
        data->m_currentVelocity = data->m_desiredVelocity;
    }

    // Now update the scroll position based on the distance traveled.
    if (distanceTraveled >= fabs(data->m_desiredPos - *data->m_currentPos)) {
        // We've traveled far enough to reach the desired position.  Stop smooth
        // scrolling.
        *data->m_currentPos = data->m_desiredPos;
        data->m_currentVelocity = 0;
        data->m_desiredVelocity = 0;
    } else {
        // Not yet at the target position.  Travel towards it and set up the
        // next update.
        if (*data->m_currentPos > data->m_desiredPos)
            distanceTraveled = -distanceTraveled;
        *data->m_currentPos += distanceTraveled;
        data->m_animationTimer.startOneShot(animationTimerDelay);
        data->m_lastAnimationTime = WTF::currentTime();
    }

    notifyPositionChanged();
}
void ProgrammaticScrollAnimator::scrollToOffsetWithoutAnimation(const FloatPoint& offset)
{
    cancelAnimation();
    notifyPositionChanged(offset);
}
void ScrollAnimatorBase::scrollToOffsetWithoutAnimation(const FloatPoint& offset)
{
    m_currentPos = offset;
    notifyPositionChanged();
}