Index: third_party/WebKit/Source/platform/scroll/ScrollAnimator.cpp |
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollAnimator.cpp b/third_party/WebKit/Source/platform/scroll/ScrollAnimator.cpp |
index a7fb64b8ffc490b41ffdd4b3cca7192fe8a02213..c3b47315630a09445668430e1400f374fa7d5225 100644 |
--- a/third_party/WebKit/Source/platform/scroll/ScrollAnimator.cpp |
+++ b/third_party/WebKit/Source/platform/scroll/ScrollAnimator.cpp |
@@ -32,13 +32,12 @@ |
#include "platform/scroll/ScrollAnimator.h" |
#include "platform/TraceEvent.h" |
-#include "platform/graphics/GraphicsLayer.h" |
#include "platform/scroll/ScrollableArea.h" |
#include "public/platform/Platform.h" |
-#include "public/platform/WebCompositorAnimation.h" |
#include "public/platform/WebCompositorSupport.h" |
#include "wtf/CurrentTime.h" |
#include "wtf/PassRefPtr.h" |
+#include <algorithm> |
namespace blink { |
@@ -51,22 +50,21 @@ |
ScrollAnimator::ScrollAnimator(ScrollableArea* scrollableArea, WTF::TimeFunction timeFunction) |
: ScrollAnimatorBase(scrollableArea) |
- , m_lastTickTime(0.0) |
, m_timeFunction(timeFunction) |
{ |
} |
ScrollAnimator::~ScrollAnimator() |
{ |
+ cancelAnimations(); |
} |
FloatPoint ScrollAnimator::desiredTargetPosition() const |
{ |
- return m_animationCurve ? m_targetOffset : currentPosition(); |
+ return m_animationCurve ? FloatPoint(m_animationCurve->targetValue()) : currentPosition(); |
} |
-float ScrollAnimator::computeDeltaToConsume( |
- ScrollbarOrientation orientation, float pixelDelta) const |
+float ScrollAnimator::computeDeltaToConsume(ScrollbarOrientation orientation, float pixelDelta) const |
{ |
FloatPoint pos = desiredTargetPosition(); |
float currentPos = (orientation == HorizontalScrollbar) ? pos.x() : pos.y(); |
@@ -74,16 +72,7 @@ |
return (currentPos == newPos) ? 0.0f : (newPos - currentPos); |
} |
-void ScrollAnimator::resetAnimationState() |
-{ |
- ScrollAnimatorCompositorCoordinator::resetAnimationState(); |
- if (m_animationCurve) |
- m_animationCurve.clear(); |
- m_startTime = 0.0; |
-} |
- |
-ScrollResultOneDimensional ScrollAnimator::userScroll( |
- ScrollbarOrientation orientation, ScrollGranularity granularity, float step, float delta) |
+ScrollResultOneDimensional ScrollAnimator::userScroll(ScrollbarOrientation orientation, ScrollGranularity granularity, float step, float delta) |
{ |
if (!m_scrollableArea->scrollAnimatorEnabled()) |
return ScrollAnimatorBase::userScroll(orientation, granularity, step, delta); |
@@ -94,33 +83,14 @@ |
return ScrollAnimatorBase::userScroll(orientation, granularity, step, delta); |
float usedPixelDelta = computeDeltaToConsume(orientation, step * delta); |
- FloatPoint pixelDelta = (orientation == VerticalScrollbar |
- ? FloatPoint(0, usedPixelDelta) : FloatPoint(usedPixelDelta, 0)); |
+ 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) { |
- 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); |
+ if (!(targetPos - m_animationCurve->targetValue()).isZero()) |
+ m_animationCurve->updateTarget(m_timeFunction() - m_startTime, targetPos); |
return ScrollResultOneDimensional(/* didScroll */ true, /* unusedScrollDelta */ 0); |
} |
@@ -131,17 +101,16 @@ |
return ScrollResultOneDimensional(/* didScroll */ false, delta); |
} |
- m_targetOffset = targetPos; |
+ m_animationCurve = adoptPtr(Platform::current()->compositorSupport()->createScrollOffsetAnimationCurve( |
+ targetPos, |
+ WebCompositorAnimationCurve::TimingFunctionTypeEaseInOut, |
+ WebScrollOffsetAnimationCurve::ScrollDurationConstant)); |
+ |
+ m_animationCurve->setInitialValue(currentPosition()); |
m_startTime = m_timeFunction(); |
scrollableArea()->registerForAnimation(); |
- if (!m_scrollableArea->scheduleAnimation()) { |
- scrollToOffsetWithoutAnimation(targetPos); |
- resetAnimationState(); |
- return ScrollResultOneDimensional(/* didScroll */ true, /* unusedScrollDelta */ 0); |
- } |
- |
- m_runState = RunState::WaitingToSendToCompositor; |
+ animationTimerFired(); |
return ScrollResultOneDimensional(/* didScroll */ true, /* unusedScrollDelta */ 0); |
} |
@@ -150,23 +119,34 @@ |
m_currentPosX = offset.x(); |
m_currentPosY = offset.y(); |
- resetAnimationState(); |
+ cancelAnimations(); |
notifyPositionChanged(); |
} |
-void ScrollAnimator::tickAnimation(double monotonicTime) |
+void ScrollAnimator::cancelAnimations() |
{ |
- m_lastTickTime = monotonicTime; |
+ if (m_animationCurve) |
+ m_animationCurve.clear(); |
+} |
- if (m_runState != RunState::RunningOnMainThread) |
- return; |
+void ScrollAnimator::serviceScrollAnimations() |
+{ |
+ if (hasRunningAnimation()) |
+ animationTimerFired(); |
+} |
- TRACE_EVENT0("blink", "ScrollAnimator::tickAnimation"); |
- double elapsedTime = monotonicTime - m_startTime; |
+bool ScrollAnimator::hasRunningAnimation() const |
+{ |
+ return m_animationCurve; |
+} |
+ |
+void ScrollAnimator::animationTimerFired() |
+{ |
+ TRACE_EVENT0("blink", "ScrollAnimator::animationTimerFired"); |
+ double elapsedTime = m_timeFunction() - m_startTime; |
bool isFinished = (elapsedTime > m_animationCurve->duration()); |
- FloatPoint offset = isFinished ? m_animationCurve->targetValue() |
- : m_animationCurve->getValue(elapsedTime); |
+ FloatPoint offset = isFinished ? m_animationCurve->targetValue() : m_animationCurve->getValue(elapsedTime); |
offset = FloatPoint(m_scrollableArea->clampScrollPosition(offset)); |
@@ -174,111 +154,12 @@ |
m_currentPosY = offset.y(); |
if (isFinished) |
- resetAnimationState(); |
+ m_animationCurve.clear(); |
else |
scrollableArea()->scheduleAnimation(); |
TRACE_EVENT0("blink", "ScrollAnimator::notifyPositionChanged"); |
notifyPositionChanged(); |
-} |
- |
-void ScrollAnimator::updateCompositorAnimations() |
-{ |
- if (m_compositorAnimationId && m_runState != RunState::RunningOnCompositor |
- && m_runState != RunState::RunningOnCompositorButNeedsUpdate) { |
- // 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); |
- |
- abortAnimation(); |
- |
- m_compositorAnimationId = 0; |
- m_compositorAnimationGroupId = 0; |
- if (m_runState == RunState::WaitingToCancelOnCompositor) { |
- resetAnimationState(); |
- return; |
- } |
- } |
- |
- if (m_runState == RunState::WaitingToSendToCompositor |
- || m_runState == RunState::RunningOnCompositorButNeedsUpdate) { |
- if (m_runState == RunState::RunningOnCompositorButNeedsUpdate) { |
- // Abort the running animation before a new one with an updated |
- // target is added. |
- abortAnimation(); |
- |
- m_compositorAnimationId = 0; |
- m_compositorAnimationGroupId = 0; |
- |
- m_animationCurve->updateTarget(m_lastTickTime - m_startTime, |
- m_targetOffset); |
- m_runState = RunState::WaitingToSendToCompositor; |
- } |
- |
- if (!m_animationCurve) { |
- m_animationCurve = adoptPtr(Platform::current()->compositorSupport() |
- ->createScrollOffsetAnimationCurve( |
- m_targetOffset, |
- WebCompositorAnimationCurve::TimingFunctionTypeEaseInOut, |
- WebScrollOffsetAnimationCurve::ScrollDurationConstant)); |
- m_animationCurve->setInitialValue(currentPosition()); |
- } |
- |
- bool sentToCompositor = false; |
- if (GraphicsLayer* layer = m_scrollableArea->layerForScrolling()) { |
- ASSERT(layer->scrollableArea() == m_scrollableArea); |
- if (!layer->platformLayer()->shouldScrollOnMainThread()) { |
- OwnPtr<WebCompositorAnimation> animation = adoptPtr( |
- Platform::current()->compositorSupport()->createAnimation( |
- *m_animationCurve, |
- WebCompositorAnimation::TargetPropertyScrollOffset)); |
- // Being here means that either there is an animation that needs |
- // to be sent to the compositor, or an animation that needs to |
- // be updated (a new scroll event before the previous animation |
- // is finished). In either case, the start time is when the |
- // first animation was initiated. This re-targets the animation |
- // using the current time on main thread. |
- animation->setStartTime(m_startTime); |
- |
- int animationId = animation->id(); |
- int animationGroupId = animation->group(); |
- |
- sentToCompositor = addAnimation(animation.release()); |
- if (sentToCompositor) { |
- m_runState = RunState::RunningOnCompositor; |
- m_compositorAnimationId = animationId; |
- m_compositorAnimationGroupId = animationGroupId; |
- } |
- } |
- } |
- |
- if (!sentToCompositor) { |
- m_runState = RunState::RunningOnMainThread; |
- if (!m_scrollableArea->scheduleAnimation()) { |
- scrollToOffsetWithoutAnimation(m_targetOffset); |
- resetAnimationState(); |
- } |
- } |
- } |
-} |
- |
-void ScrollAnimator::notifyCompositorAnimationFinished(int groupId) |
-{ |
- ScrollAnimatorCompositorCoordinator::compositorAnimationFinished(groupId); |
-} |
- |
-void ScrollAnimator::cancelAnimation() |
-{ |
- ScrollAnimatorCompositorCoordinator::cancelAnimation(); |
-} |
- |
-void ScrollAnimator::layerForCompositedScrollingDidChange( |
- WebCompositorAnimationTimeline* timeline) |
-{ |
- reattachCompositorPlayerIfNeeded(timeline); |
} |
DEFINE_TRACE(ScrollAnimator) |