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())); } } }
void ScrollAnimator::layerForCompositedScrollingDidChange( CompositorAnimationTimeline* timeline) { if (reattachCompositorPlayerIfNeeded(timeline) && m_animationCurve) addMainThreadScrollingReason(); }
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); }