Beispiel #1
0
void ProgrammaticScrollAnimator::updateCompositorAnimations() {
  if (m_runState == RunState::PostAnimationCleanup) {
    // No special cleanup, simply reset animation state. We have this state
    // here because the state machine is shared with ScrollAnimator which
    // has to do some cleanup that requires the compositing state to be clean.
    return resetAnimationState();
  }

  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) {
    if (!m_compositorAnimationAttachedToElementId)
      reattachCompositorPlayerIfNeeded(
          getScrollableArea()->compositorAnimationTimeline());

    bool sentToCompositor = false;

    if (!m_scrollableArea->shouldScrollOnMainThread()) {
      std::unique_ptr<CompositorAnimation> animation =
          CompositorAnimation::create(
              *m_animationCurve, CompositorTargetProperty::SCROLL_OFFSET, 0, 0);

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

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

    if (!sentToCompositor) {
      m_runState = RunState::RunningOnMainThread;
      m_animationCurve->setInitialValue(
          compositorOffsetFromBlinkOffset(m_scrollableArea->getScrollOffset()));
      if (!m_scrollableArea->scheduleAnimation()) {
        notifyOffsetChanged(m_targetOffset);
        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()));
        }
    }
}
Beispiel #3
0
void ScrollAnimator::layerForCompositedScrollingDidChange(
    CompositorAnimationTimeline* timeline) {
  if (reattachCompositorPlayerIfNeeded(timeline) && m_animationCurve)
    addMainThreadScrollingReason();
}
Beispiel #4
0
void ScrollAnimator::updateCompositorAnimations() {
  ScrollAnimatorCompositorCoordinator::updateCompositorAnimations();

  if (m_runState == RunState::PostAnimationCleanup) {
    postAnimationCleanupAndReset();
    return;
  }

  if (m_runState == RunState::WaitingToCancelOnCompositor) {
    DCHECK(m_compositorAnimationId);
    abortAnimation();
    postAnimationCleanupAndReset();
    return;
  }

  if (m_runState == RunState::RunningOnCompositorButNeedsTakeover) {
    // The call to ::takeOverCompositorAnimation aborted the animation and
    // put us in this state. The assumption is that takeOver is called
    // because a main thread scrolling reason is added, and simply trying
    // to ::sendAnimationToCompositor will fail and we will run on the main
    // thread.
    resetAnimationIds();
    m_runState = RunState::WaitingToSendToCompositor;
  }

  if (m_runState == RunState::RunningOnCompositorButNeedsUpdate ||
      m_runState == RunState::WaitingToCancelOnCompositorButNewScroll ||
      m_runState == RunState::RunningOnCompositorButNeedsAdjustment) {
    // Abort the running animation before a new one with an updated
    // target is added.
    abortAnimation();
    resetAnimationIds();

    if (m_runState != RunState::RunningOnCompositorButNeedsAdjustment) {
      // When in RunningOnCompositorButNeedsAdjustment, the call to
      // ::adjustScrollOffsetAnimation should have made the necessary
      // adjustment to the curve.
      m_animationCurve->updateTarget(
          m_timeFunction() - m_startTime,
          compositorOffsetFromBlinkOffset(m_targetOffset));
    }

    if (m_runState == RunState::WaitingToCancelOnCompositorButNewScroll) {
      m_animationCurve->setInitialValue(
          compositorOffsetFromBlinkOffset(currentOffset()));
    }

    m_runState = RunState::WaitingToSendToCompositor;
  }

  if (m_runState == RunState::WaitingToSendToCompositor) {
    if (!m_compositorAnimationAttachedToElementId)
      reattachCompositorPlayerIfNeeded(
          getScrollableArea()->compositorAnimationTimeline());

    if (!m_animationCurve)
      createAnimationCurve();

    bool runningOnMainThread = false;
    bool sentToCompositor = sendAnimationToCompositor();
    if (!sentToCompositor) {
      runningOnMainThread = registerAndScheduleAnimation();
      if (runningOnMainThread)
        m_runState = RunState::RunningOnMainThread;
    }

    // Main thread should deal with the scroll animations it started.
    if (sentToCompositor || runningOnMainThread)
      addMainThreadScrollingReason();
    else
      removeMainThreadScrollingReason();
  }
}
void ScrollAnimator::layerForCompositedScrollingDidChange(
    WebCompositorAnimationTimeline* timeline)
{
    reattachCompositorPlayerIfNeeded(timeline);
}