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 ScrollAnimator::scrollToOffsetWithoutAnimation( const ScrollOffset& offset) { m_currentOffset = offset; resetAnimationState(); notifyOffsetChanged(); }
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()); ScrollOffset offset = blinkOffsetFromCompositorOffset(m_animationCurve->getValue(elapsedTime)); notifyOffsetChanged(offset); if (isFinished) { m_runState = RunState::PostAnimationCleanup; } else if (!m_scrollableArea->scheduleAnimation()) { notifyOffsetChanged(offset); resetAnimationState(); } }
ScrollResult ScrollAnimatorBase::userScroll(ScrollGranularity, const ScrollOffset& delta) { ScrollOffset consumedDelta = computeDeltaToConsume(delta); ScrollOffset newPos = m_currentOffset + consumedDelta; if (m_currentOffset == newPos) return ScrollResult(false, false, delta.width(), delta.height()); m_currentOffset = newPos; notifyOffsetChanged(); return ScrollResult(consumedDelta.width(), consumedDelta.height(), delta.width() - consumedDelta.width(), delta.height() - consumedDelta.height()); }
void ProgrammaticScrollAnimator::animateToOffset(const ScrollOffset& offset) { if (m_runState == RunState::PostAnimationCleanup) resetAnimationState(); m_startTime = 0.0; m_targetOffset = offset; m_animationCurve = CompositorScrollOffsetAnimationCurve::create( compositorOffsetFromBlinkOffset(m_targetOffset), CompositorScrollOffsetAnimationCurve::ScrollDurationDeltaBased); m_scrollableArea->registerForAnimation(); if (!m_scrollableArea->scheduleAnimation()) { resetAnimationState(); notifyOffsetChanged(offset); } m_runState = RunState::WaitingToSendToCompositor; }
void ProgrammaticScrollAnimator::layerForCompositedScrollingDidChange( CompositorAnimationTimeline* 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( compositorOffsetFromBlinkOffset(m_scrollableArea->getScrollOffset())); m_scrollableArea->registerForAnimation(); if (!m_scrollableArea->scheduleAnimation()) { resetAnimationState(); notifyOffsetChanged(m_targetOffset); } } }
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()); ScrollOffset offset = blinkOffsetFromCompositorOffset( isFinished ? m_animationCurve->targetValue() : m_animationCurve->getValue(elapsedTime)); offset = m_scrollableArea->clampScrollOffset(offset); m_currentOffset = offset; if (isFinished) m_runState = RunState::PostAnimationCleanup; else getScrollableArea()->scheduleAnimation(); TRACE_EVENT0("blink", "ScrollAnimator::notifyOffsetChanged"); notifyOffsetChanged(); }
void ProgrammaticScrollAnimator::scrollToOffsetWithoutAnimation( const ScrollOffset& offset) { cancelAnimation(); notifyOffsetChanged(offset); }