Exemplo n.º 1
0
void ScrollAnimator::adjustAnimationAndSetScrollOffset(
    const ScrollOffset& offset,
    ScrollType scrollType) {
  IntSize adjustment =
      roundedIntSize(offset) - roundedIntSize(m_scrollableArea->scrollOffset());
  scrollOffsetChanged(offset, scrollType);

  if (m_runState == RunState::Idle) {
    adjustImplOnlyScrollOffsetAnimation(adjustment);
  } else if (hasRunningAnimation()) {
    m_targetOffset += ScrollOffset(adjustment);
    if (m_animationCurve) {
      m_animationCurve->applyAdjustment(adjustment);
      if (m_runState != RunState::RunningOnMainThread &&
          registerAndScheduleAnimation())
        m_runState = RunState::RunningOnCompositorButNeedsAdjustment;
    }
  }
}
Exemplo n.º 2
0
void ScrollAnimator::notifyAnimationTakeover(
    double monotonicTime,
    double animationStartTime,
    std::unique_ptr<cc::AnimationCurve> curve) {
  // If there is already an animation running and the compositor asks to take
  // over an animation, do nothing to avoid judder.
  if (hasRunningAnimation())
    return;

  cc::ScrollOffsetAnimationCurve* scrollOffsetAnimationCurve =
      curve->ToScrollOffsetAnimationCurve();
  ScrollOffset targetValue(scrollOffsetAnimationCurve->target_value().x(),
                           scrollOffsetAnimationCurve->target_value().y());
  if (willAnimateToOffset(targetValue)) {
    m_animationCurve = CompositorScrollOffsetAnimationCurve::create(
        std::move(scrollOffsetAnimationCurve));
    m_startTime = animationStartTime;
  }
}
Exemplo n.º 3
0
ScrollResult ScrollAnimator::userScroll(ScrollGranularity granularity,
                                        const ScrollOffset& delta) {
  if (!m_scrollableArea->scrollAnimatorEnabled())
    return ScrollAnimatorBase::userScroll(granularity, delta);

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

  if (granularity == ScrollByPrecisePixel) {
    // Cancel scroll animation because asked to instant scroll.
    if (hasRunningAnimation())
      cancelAnimation();
    return ScrollAnimatorBase::userScroll(granularity, delta);
  }

  bool needsPostAnimationCleanup = m_runState == RunState::PostAnimationCleanup;
  if (m_runState == RunState::PostAnimationCleanup)
    resetAnimationState();

  ScrollOffset consumedDelta = computeDeltaToConsume(delta);
  ScrollOffset targetOffset = desiredTargetOffset();
  targetOffset += consumedDelta;

  if (willAnimateToOffset(targetOffset)) {
    m_lastGranularity = granularity;
    // Report unused delta only if there is no animation running. See
    // comment below regarding scroll latching.
    // TODO(bokan): Need to standardize how ScrollAnimators report
    // unusedDelta. This differs from ScrollAnimatorMac currently.
    return ScrollResult(true, true, 0, 0);
  }

  // If the run state when this method was called was PostAnimationCleanup and
  // we're not starting an animation, stay in PostAnimationCleanup state so
  // that the main thread scrolling reason can be removed.
  if (needsPostAnimationCleanup)
    m_runState = RunState::PostAnimationCleanup;

  // Report unused delta only if there is no animation and we are not
  // starting one. This ensures we latch for the duration of the
  // animation rather than animating multiple scrollers at the same time.
  return ScrollResult(false, false, delta.width(), delta.height());
}
Exemplo n.º 4
0
ScrollResultOneDimensional ScrollAnimator::userScroll(
    ScrollbarOrientation orientation, ScrollGranularity granularity, float step, float delta)
{
    if (!m_scrollableArea->scrollAnimatorEnabled())
        return ScrollAnimatorBase::userScroll(orientation, granularity, step, delta);

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

    if (granularity == ScrollByPrecisePixel) {
        if (hasRunningAnimation()) {
            abortAnimation();
            resetAnimationState();
        }
        return ScrollAnimatorBase::userScroll(orientation, granularity, step, delta);
    }

    float usedPixelDelta = computeDeltaToConsume(orientation, step * delta);
    FloatPoint pixelDelta = (orientation == VerticalScrollbar
        ? FloatPoint(0, usedPixelDelta) : FloatPoint(usedPixelDelta, 0));

    FloatPoint targetPos = desiredTargetPosition();
    targetPos.moveBy(pixelDelta);

    if (m_animationCurve) {
        if ((targetPos - m_targetOffset).isZero()) {
            // Report unused delta only if there is no animation running. See
            // comment below regarding scroll latching.
            return ScrollResultOneDimensional(/* didScroll */ true, /* unusedScrollDelta */ 0);
        }

        m_targetOffset = targetPos;
        ASSERT(m_runState == RunState::RunningOnMainThread
            || m_runState == RunState::RunningOnCompositor
            || m_runState == RunState::RunningOnCompositorButNeedsUpdate);

        if (m_runState == RunState::RunningOnCompositor
            || m_runState == RunState::RunningOnCompositorButNeedsUpdate) {
            if (registerAndScheduleAnimation())
                m_runState = RunState::RunningOnCompositorButNeedsUpdate;
            return ScrollResultOneDimensional(/* didScroll */ true, /* unusedScrollDelta */ 0);
        }

        // Running on the main thread, simply update the target offset instead
        // of sending to the compositor.
        m_animationCurve->updateTarget(m_timeFunction() - m_startTime, targetPos);
        return ScrollResultOneDimensional(/* didScroll */ true, /* unusedScrollDelta */ 0);
    }

    if ((targetPos - currentPosition()).isZero()) {
        // Report unused delta only if there is no animation and we are not
        // starting one. This ensures we latch for the duration of the
        // animation rather than animating multiple scrollers at the same time.
        return ScrollResultOneDimensional(/* didScroll */ false, delta);
    }

    m_targetOffset = targetPos;
    m_startTime = m_timeFunction();
    m_lastGranularity = granularity;

    if (registerAndScheduleAnimation())
        m_runState = RunState::WaitingToSendToCompositor;

    return ScrollResultOneDimensional(/* didScroll */ true, /* unusedScrollDelta */ 0);
}