summaryrefslogtreecommitdiffstats
path: root/third_party/WebKit/Source
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/WebKit/Source')
-rw-r--r--third_party/WebKit/Source/core/frame/FrameView.cpp2
-rw-r--r--third_party/WebKit/Source/core/input/EventHandler.cpp4
-rw-r--r--third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp5
-rw-r--r--third_party/WebKit/Source/platform/graphics/GraphicsLayer.h1
-rw-r--r--third_party/WebKit/Source/platform/mac/ScrollAnimatorMac.h2
-rw-r--r--third_party/WebKit/Source/platform/mac/ScrollAnimatorMac.mm2
-rw-r--r--third_party/WebKit/Source/platform/scroll/ProgrammaticScrollAnimator.cpp7
-rw-r--r--third_party/WebKit/Source/platform/scroll/ProgrammaticScrollAnimator.h1
-rw-r--r--third_party/WebKit/Source/platform/scroll/ScrollAnimator.cpp191
-rw-r--r--third_party/WebKit/Source/platform/scroll/ScrollAnimator.h19
-rw-r--r--third_party/WebKit/Source/platform/scroll/ScrollAnimatorBase.cpp1
-rw-r--r--third_party/WebKit/Source/platform/scroll/ScrollAnimatorBase.h17
-rw-r--r--third_party/WebKit/Source/platform/scroll/ScrollAnimatorCompositorCoordinator.cpp14
-rw-r--r--third_party/WebKit/Source/platform/scroll/ScrollAnimatorCompositorCoordinator.h6
-rw-r--r--third_party/WebKit/Source/platform/scroll/ScrollAnimatorTest.cpp32
-rw-r--r--third_party/WebKit/Source/platform/scroll/ScrollableArea.cpp14
-rw-r--r--third_party/WebKit/Source/platform/scroll/ScrollableArea.h2
17 files changed, 250 insertions, 70 deletions
diff --git a/third_party/WebKit/Source/core/frame/FrameView.cpp b/third_party/WebKit/Source/core/frame/FrameView.cpp
index 2b39cef..de49f4b 100644
--- a/third_party/WebKit/Source/core/frame/FrameView.cpp
+++ b/third_party/WebKit/Source/core/frame/FrameView.cpp
@@ -264,7 +264,7 @@ void FrameView::dispose()
RELEASE_ASSERT(!isInPerformLayout());
if (ScrollAnimatorBase* scrollAnimator = existingScrollAnimator())
- scrollAnimator->cancelAnimations();
+ scrollAnimator->cancelAnimation();
cancelProgrammaticScrollAnimation();
detachScrollbars();
diff --git a/third_party/WebKit/Source/core/input/EventHandler.cpp b/third_party/WebKit/Source/core/input/EventHandler.cpp
index 515e550..47861ee 100644
--- a/third_party/WebKit/Source/core/input/EventHandler.cpp
+++ b/third_party/WebKit/Source/core/input/EventHandler.cpp
@@ -2036,14 +2036,14 @@ WebInputEventResult EventHandler::handleGestureShowPress()
if (!view)
return WebInputEventResult::NotHandled;
if (ScrollAnimatorBase* scrollAnimator = view->existingScrollAnimator())
- scrollAnimator->cancelAnimations();
+ scrollAnimator->cancelAnimation();
const FrameView::ScrollableAreaSet* areas = view->scrollableAreas();
if (!areas)
return WebInputEventResult::NotHandled;
for (const ScrollableArea* scrollableArea : *areas) {
ScrollAnimatorBase* animator = scrollableArea->existingScrollAnimator();
if (animator)
- animator->cancelAnimations();
+ animator->cancelAnimation();
}
return WebInputEventResult::NotHandled;
}
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp b/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp
index eefb444..bbb2640 100644
--- a/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp
+++ b/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp
@@ -1128,6 +1128,11 @@ void GraphicsLayer::removeAnimation(int animationId)
platformLayer()->removeAnimation(animationId);
}
+void GraphicsLayer::abortAnimation(int animationId)
+{
+ platformLayer()->abortAnimation(animationId);
+}
+
WebLayer* GraphicsLayer::platformLayer() const
{
return m_layer->layer();
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsLayer.h b/third_party/WebKit/Source/platform/graphics/GraphicsLayer.h
index 8f52c48..caa5158 100644
--- a/third_party/WebKit/Source/platform/graphics/GraphicsLayer.h
+++ b/third_party/WebKit/Source/platform/graphics/GraphicsLayer.h
@@ -203,6 +203,7 @@ public:
bool addAnimation(PassOwnPtr<WebCompositorAnimation>);
void pauseAnimation(int animationId, double /*timeOffset*/);
void removeAnimation(int animationId);
+ void abortAnimation(int animationId);
// Layer contents
void setContentsToImage(Image*, RespectImageOrientationEnum = DoNotRespectImageOrientation);
diff --git a/third_party/WebKit/Source/platform/mac/ScrollAnimatorMac.h b/third_party/WebKit/Source/platform/mac/ScrollAnimatorMac.h
index b5805bc..35c19f4e 100644
--- a/third_party/WebKit/Source/platform/mac/ScrollAnimatorMac.h
+++ b/third_party/WebKit/Source/platform/mac/ScrollAnimatorMac.h
@@ -93,7 +93,7 @@ private:
void handleWheelEventPhase(PlatformWheelEventPhase) override;
- void cancelAnimations() override;
+ void cancelAnimation() override;
void setIsActive() override;
void contentAreaWillPaint() const override;
diff --git a/third_party/WebKit/Source/platform/mac/ScrollAnimatorMac.mm b/third_party/WebKit/Source/platform/mac/ScrollAnimatorMac.mm
index c99941a..a731a46 100644
--- a/third_party/WebKit/Source/platform/mac/ScrollAnimatorMac.mm
+++ b/third_party/WebKit/Source/platform/mac/ScrollAnimatorMac.mm
@@ -1041,7 +1041,7 @@ bool ScrollAnimatorMac::setScrollbarsVisibleForTesting(bool show)
return false;
}
-void ScrollAnimatorMac::cancelAnimations()
+void ScrollAnimatorMac::cancelAnimation()
{
m_haveScrolledSincePageLoad = false;
diff --git a/third_party/WebKit/Source/platform/scroll/ProgrammaticScrollAnimator.cpp b/third_party/WebKit/Source/platform/scroll/ProgrammaticScrollAnimator.cpp
index 6910c4f..3e29f04 100644
--- a/third_party/WebKit/Source/platform/scroll/ProgrammaticScrollAnimator.cpp
+++ b/third_party/WebKit/Source/platform/scroll/ProgrammaticScrollAnimator.cpp
@@ -64,6 +64,12 @@ void ProgrammaticScrollAnimator::animateToOffset(FloatPoint offset)
m_runState = RunState::WaitingToSendToCompositor;
}
+void ProgrammaticScrollAnimator::cancelAnimation()
+{
+ ASSERT(m_runState != RunState::RunningOnCompositorButNeedsUpdate);
+ ScrollAnimatorCompositorCoordinator::cancelAnimation();
+}
+
void ProgrammaticScrollAnimator::tickAnimation(double monotonicTime)
{
if (m_runState != RunState::RunningOnMainThread)
@@ -154,6 +160,7 @@ void ProgrammaticScrollAnimator::layerForCompositedScrollingDidChange(WebComposi
void ProgrammaticScrollAnimator::notifyCompositorAnimationFinished(int groupId)
{
+ ASSERT(m_runState != RunState::RunningOnCompositorButNeedsUpdate);
ScrollAnimatorCompositorCoordinator::compositorAnimationFinished(groupId);
}
diff --git a/third_party/WebKit/Source/platform/scroll/ProgrammaticScrollAnimator.h b/third_party/WebKit/Source/platform/scroll/ProgrammaticScrollAnimator.h
index c700414..fa05677 100644
--- a/third_party/WebKit/Source/platform/scroll/ProgrammaticScrollAnimator.h
+++ b/third_party/WebKit/Source/platform/scroll/ProgrammaticScrollAnimator.h
@@ -34,6 +34,7 @@ public:
// ScrollAnimatorCompositorCoordinator implementation.
void resetAnimationState() override;
+ void cancelAnimation() override;
ScrollableArea* scrollableArea() const override { return m_scrollableArea; }
void tickAnimation(double monotonicTime) override;
void updateCompositorAnimations() override;
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollAnimator.cpp b/third_party/WebKit/Source/platform/scroll/ScrollAnimator.cpp
index e9610b0..fa45f0f 100644
--- a/third_party/WebKit/Source/platform/scroll/ScrollAnimator.cpp
+++ b/third_party/WebKit/Source/platform/scroll/ScrollAnimator.cpp
@@ -31,12 +31,13 @@
#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 {
@@ -49,21 +50,22 @@ PassOwnPtrWillBeRawPtr<ScrollAnimatorBase> ScrollAnimatorBase::create(Scrollable
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 ? FloatPoint(m_animationCurve->targetValue()) : currentPosition();
+ return m_animationCurve ? m_targetOffset : 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();
@@ -71,7 +73,16 @@ float ScrollAnimator::computeDeltaToConsume(ScrollbarOrientation orientation, fl
return (currentPos == newPos) ? 0.0f : (newPos - currentPos);
}
-ScrollResultOneDimensional ScrollAnimator::userScroll(ScrollbarOrientation orientation, ScrollGranularity granularity, float step, float delta)
+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)
{
if (!m_scrollableArea->scrollAnimatorEnabled())
return ScrollAnimatorBase::userScroll(orientation, granularity, step, delta);
@@ -82,14 +93,33 @@ ScrollResultOneDimensional ScrollAnimator::userScroll(ScrollbarOrientation orien
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_animationCurve->targetValue()).isZero())
- m_animationCurve->updateTarget(m_timeFunction() - m_startTime, targetPos);
+ 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);
return ScrollResultOneDimensional(/* didScroll */ true, /* unusedScrollDelta */ 0);
}
@@ -100,16 +130,17 @@ ScrollResultOneDimensional ScrollAnimator::userScroll(ScrollbarOrientation orien
return ScrollResultOneDimensional(/* didScroll */ false, delta);
}
- m_animationCurve = adoptPtr(Platform::current()->compositorSupport()->createScrollOffsetAnimationCurve(
- targetPos,
- WebCompositorAnimationCurve::TimingFunctionTypeEaseInOut,
- WebScrollOffsetAnimationCurve::ScrollDurationConstant));
-
- m_animationCurve->setInitialValue(currentPosition());
+ m_targetOffset = targetPos;
m_startTime = m_timeFunction();
scrollableArea()->registerForAnimation();
- animationTimerFired();
+ if (!m_scrollableArea->scheduleAnimation()) {
+ scrollToOffsetWithoutAnimation(targetPos);
+ resetAnimationState();
+ return ScrollResultOneDimensional(/* didScroll */ true, /* unusedScrollDelta */ 0);
+ }
+
+ m_runState = RunState::WaitingToSendToCompositor;
return ScrollResultOneDimensional(/* didScroll */ true, /* unusedScrollDelta */ 0);
}
@@ -118,34 +149,23 @@ void ScrollAnimator::scrollToOffsetWithoutAnimation(const FloatPoint& offset)
m_currentPosX = offset.x();
m_currentPosY = offset.y();
- cancelAnimations();
+ resetAnimationState();
notifyPositionChanged();
}
-void ScrollAnimator::cancelAnimations()
+void ScrollAnimator::tickAnimation(double monotonicTime)
{
- if (m_animationCurve)
- m_animationCurve.clear();
-}
+ m_lastTickTime = monotonicTime;
-void ScrollAnimator::serviceScrollAnimations()
-{
- if (hasRunningAnimation())
- animationTimerFired();
-}
+ if (m_runState != RunState::RunningOnMainThread)
+ return;
-bool ScrollAnimator::hasRunningAnimation() const
-{
- return m_animationCurve;
-}
-
-void ScrollAnimator::animationTimerFired()
-{
- TRACE_EVENT0("blink", "ScrollAnimator::animationTimerFired");
- double elapsedTime = m_timeFunction() - m_startTime;
+ TRACE_EVENT0("blink", "ScrollAnimator::tickAnimation");
+ double elapsedTime = monotonicTime - 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));
@@ -153,7 +173,7 @@ void ScrollAnimator::animationTimerFired()
m_currentPosY = offset.y();
if (isFinished)
- m_animationCurve.clear();
+ resetAnimationState();
else
scrollableArea()->scheduleAnimation();
@@ -161,6 +181,105 @@ void ScrollAnimator::animationTimerFired()
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)
{
ScrollAnimatorBase::trace(visitor);
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollAnimator.h b/third_party/WebKit/Source/platform/scroll/ScrollAnimator.h
index 01746e68..5d8f20a 100644
--- a/third_party/WebKit/Source/platform/scroll/ScrollAnimator.h
+++ b/third_party/WebKit/Source/platform/scroll/ScrollAnimator.h
@@ -34,11 +34,14 @@
#include "platform/Timer.h"
#include "platform/geometry/FloatPoint.h"
#include "platform/scroll/ScrollAnimatorBase.h"
+#include "public/platform/WebCompositorAnimationDelegate.h"
+#include "public/platform/WebCompositorAnimationPlayerClient.h"
#include "public/platform/WebScrollOffsetAnimationCurve.h"
namespace blink {
class ScrollAnimatorTest;
+class WebCompositorAnimationTimeline;
class PLATFORM_EXPORT ScrollAnimator final : public ScrollAnimatorBase {
public:
@@ -50,20 +53,26 @@ public:
ScrollResultOneDimensional userScroll(ScrollbarOrientation, ScrollGranularity, float step, float delta) override;
void scrollToOffsetWithoutAnimation(const FloatPoint&) override;
- void cancelAnimations() override;
- void serviceScrollAnimations() override;
- bool hasRunningAnimation() const override;
+ // ScrollAnimatorCompositorCoordinator implementation.
+ void tickAnimation(double monotonicTime) override;
+ void cancelAnimation() override;
+ void resetAnimationState() override;
+ void updateCompositorAnimations() override;
+ void notifyCompositorAnimationFinished(int groupId) override;
+ void layerForCompositedScrollingDidChange(WebCompositorAnimationTimeline*) override;
DECLARE_VIRTUAL_TRACE();
protected:
- void animationTimerFired();
-
OwnPtr<WebScrollOffsetAnimationCurve> m_animationCurve;
+ double m_lastTickTime;
double m_startTime;
WTF::TimeFunction m_timeFunction;
+
private:
FloatPoint desiredTargetPosition() const;
+
+ FloatPoint m_targetOffset;
};
} // namespace blink
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollAnimatorBase.cpp b/third_party/WebKit/Source/platform/scroll/ScrollAnimatorBase.cpp
index ce86e06..75306cc 100644
--- a/third_party/WebKit/Source/platform/scroll/ScrollAnimatorBase.cpp
+++ b/third_party/WebKit/Source/platform/scroll/ScrollAnimatorBase.cpp
@@ -104,6 +104,7 @@ float ScrollAnimatorBase::clampScrollPosition(ScrollbarOrientation orientation,
DEFINE_TRACE(ScrollAnimatorBase)
{
visitor->trace(m_scrollableArea);
+ ScrollAnimatorCompositorCoordinator::trace(visitor);
}
} // namespace blink
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollAnimatorBase.h b/third_party/WebKit/Source/platform/scroll/ScrollAnimatorBase.h
index 3503b7f..5926f86 100644
--- a/third_party/WebKit/Source/platform/scroll/ScrollAnimatorBase.h
+++ b/third_party/WebKit/Source/platform/scroll/ScrollAnimatorBase.h
@@ -35,6 +35,7 @@
#include "platform/PlatformWheelEvent.h"
#include "platform/geometry/FloatSize.h"
#include "platform/heap/Handle.h"
+#include "platform/scroll/ScrollAnimatorCompositorCoordinator.h"
#include "platform/scroll/ScrollTypes.h"
#include "wtf/Forward.h"
@@ -43,8 +44,9 @@ namespace blink {
class FloatPoint;
class ScrollableArea;
class Scrollbar;
+class WebCompositorAnimationTimeline;
-class PLATFORM_EXPORT ScrollAnimatorBase : public NoBaseWillBeGarbageCollectedFinalized<ScrollAnimatorBase> {
+class PLATFORM_EXPORT ScrollAnimatorBase : public ScrollAnimatorCompositorCoordinator {
public:
static PassOwnPtrWillBeRawPtr<ScrollAnimatorBase> create(ScrollableArea*);
@@ -61,8 +63,6 @@ public:
virtual void scrollToOffsetWithoutAnimation(const FloatPoint&);
- ScrollableArea* scrollableArea() const { return m_scrollableArea; }
-
virtual void setIsActive() { }
#if OS(MACOSX)
@@ -76,9 +76,14 @@ public:
// area.
virtual float computeDeltaToConsume(ScrollbarOrientation, float pixelDelta) const;
- virtual void cancelAnimations() { }
- virtual void serviceScrollAnimations() { }
- virtual bool hasRunningAnimation() const { return false; }
+
+ // ScrollAnimatorCompositorCoordinator implementation.
+ ScrollableArea* scrollableArea() const override { return m_scrollableArea; }
+ void tickAnimation(double monotonicTime) override { };
+ void cancelAnimation() override { }
+ void updateCompositorAnimations() override { };
+ void notifyCompositorAnimationFinished(int groupId) override { };
+ void layerForCompositedScrollingDidChange(WebCompositorAnimationTimeline*) override { };
virtual void contentAreaWillPaint() const { }
virtual void mouseEnteredContentArea() const { }
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollAnimatorCompositorCoordinator.cpp b/third_party/WebKit/Source/platform/scroll/ScrollAnimatorCompositorCoordinator.cpp
index 9245749..4f0528f 100644
--- a/third_party/WebKit/Source/platform/scroll/ScrollAnimatorCompositorCoordinator.cpp
+++ b/third_party/WebKit/Source/platform/scroll/ScrollAnimatorCompositorCoordinator.cpp
@@ -51,6 +51,7 @@ bool ScrollAnimatorCompositorCoordinator::hasAnimationThatRequiresService() cons
return false;
case RunState::WaitingToSendToCompositor:
case RunState::RunningOnMainThread:
+ case RunState::RunningOnCompositorButNeedsUpdate:
case RunState::WaitingToCancelOnCompositor:
return true;
}
@@ -83,6 +84,17 @@ void ScrollAnimatorCompositorCoordinator::removeAnimation()
}
}
+void ScrollAnimatorCompositorCoordinator::abortAnimation()
+{
+ if (m_compositorPlayer) {
+ if (m_compositorPlayer->isLayerAttached())
+ m_compositorPlayer->abortAnimation(m_compositorAnimationId);
+ } else {
+ if (GraphicsLayer* layer = scrollableArea()->layerForScrolling())
+ layer->abortAnimation(m_compositorAnimationId);
+ }
+}
+
void ScrollAnimatorCompositorCoordinator::cancelAnimation()
{
switch (m_runState) {
@@ -100,6 +112,7 @@ void ScrollAnimatorCompositorCoordinator::cancelAnimation()
case RunState::RunningOnMainThread:
resetAnimationState();
break;
+ case RunState::RunningOnCompositorButNeedsUpdate:
case RunState::RunningOnCompositor:
m_runState = RunState::WaitingToCancelOnCompositor;
@@ -125,6 +138,7 @@ void ScrollAnimatorCompositorCoordinator::compositorAnimationFinished(
case RunState::WaitingToSendToCompositor:
break;
case RunState::RunningOnCompositor:
+ case RunState::RunningOnCompositorButNeedsUpdate:
case RunState::WaitingToCancelOnCompositor:
resetAnimationState();
}
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollAnimatorCompositorCoordinator.h b/third_party/WebKit/Source/platform/scroll/ScrollAnimatorCompositorCoordinator.h
index f10acb3..440aa7e 100644
--- a/third_party/WebKit/Source/platform/scroll/ScrollAnimatorCompositorCoordinator.h
+++ b/third_party/WebKit/Source/platform/scroll/ScrollAnimatorCompositorCoordinator.h
@@ -22,9 +22,9 @@ public:
virtual ~ScrollAnimatorCompositorCoordinator();
bool hasAnimationThatRequiresService() const;
- void cancelAnimation();
virtual void resetAnimationState();
+ virtual void cancelAnimation();
virtual ScrollableArea* scrollableArea() const = 0;
virtual void tickAnimation(double monotonicTime) = 0;
@@ -39,6 +39,7 @@ protected:
bool addAnimation(PassOwnPtr<WebCompositorAnimation>);
void removeAnimation();
+ void abortAnimation();
void compositorAnimationFinished(int groupId);
void reattachCompositorPlayerIfNeeded(WebCompositorAnimationTimeline*);
@@ -62,6 +63,9 @@ protected:
// Running an animation on the compositor.
RunningOnCompositor,
+ // Running an animation on the compositor but needs update.
+ RunningOnCompositorButNeedsUpdate,
+
// Running an animation on the main thread.
RunningOnMainThread,
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollAnimatorTest.cpp b/third_party/WebKit/Source/platform/scroll/ScrollAnimatorTest.cpp
index 2a398a0..cbb5be1 100644
--- a/third_party/WebKit/Source/platform/scroll/ScrollAnimatorTest.cpp
+++ b/third_party/WebKit/Source/platform/scroll/ScrollAnimatorTest.cpp
@@ -72,6 +72,7 @@ public:
MOCK_CONST_METHOD0(scrollbarsCanBeActive, bool());
MOCK_CONST_METHOD0(scrollableAreaBoundingBox, IntRect());
MOCK_METHOD0(registerForAnimation, void());
+ MOCK_METHOD0(scheduleAnimation, bool());
bool userInputScrollable(ScrollbarOrientation) const override { return true; }
bool shouldPlaceVerticalScrollbarOnLeft() const override { return false; }
@@ -100,30 +101,32 @@ static void reset(ScrollAnimator& scrollAnimator)
scrollAnimator.scrollToOffsetWithoutAnimation(FloatPoint());
}
-TEST(ScrollAnimatorTest, Enabled)
+TEST(ScrollAnimatorTest, MainThreadEnabled)
{
OwnPtrWillBeRawPtr<MockScrollableArea> scrollableArea = MockScrollableArea::create(true);
OwnPtrWillBeRawPtr<ScrollAnimator> scrollAnimator = adoptPtrWillBeNoop(new ScrollAnimator(scrollableArea.get(), getMockedTime));
EXPECT_CALL(*scrollableArea, minimumScrollPosition()).Times(AtLeast(1)).WillRepeatedly(Return(IntPoint()));
EXPECT_CALL(*scrollableArea, maximumScrollPosition()).Times(AtLeast(1)).WillRepeatedly(Return(IntPoint(1000, 1000)));
- EXPECT_CALL(*scrollableArea, setScrollOffset(_, _)).Times(12);
+ EXPECT_CALL(*scrollableArea, setScrollOffset(_, _)).Times(9);
EXPECT_CALL(*scrollableArea, registerForAnimation()).Times(3);
+ EXPECT_CALL(*scrollableArea, scheduleAnimation()).Times(AtLeast(1)).WillRepeatedly(Return(true));
- EXPECT_FALSE(scrollAnimator->hasRunningAnimation());
+ EXPECT_FALSE(scrollAnimator->hasAnimationThatRequiresService());
ScrollResultOneDimensional result = scrollAnimator->userScroll(HorizontalScrollbar, ScrollByLine, 100, -1);
- EXPECT_FALSE(scrollAnimator->hasRunningAnimation());
+ EXPECT_FALSE(scrollAnimator->hasAnimationThatRequiresService());
EXPECT_FALSE(result.didScroll);
EXPECT_FLOAT_EQ(-1.0f, result.unusedScrollDelta);
result = scrollAnimator->userScroll(HorizontalScrollbar, ScrollByLine, 100, 1);
- EXPECT_TRUE(scrollAnimator->hasRunningAnimation());
+ EXPECT_TRUE(scrollAnimator->hasAnimationThatRequiresService());
EXPECT_TRUE(result.didScroll);
EXPECT_FLOAT_EQ(0.0, result.unusedScrollDelta);
gMockedTime += 0.05;
- scrollAnimator->serviceScrollAnimations();
+ scrollAnimator->updateCompositorAnimations();
+ scrollAnimator->tickAnimation(getMockedTime());
EXPECT_NE(100, scrollAnimator->currentPosition().x());
EXPECT_NE(0, scrollAnimator->currentPosition().x());
@@ -131,10 +134,11 @@ TEST(ScrollAnimatorTest, Enabled)
reset(*scrollAnimator);
scrollAnimator->userScroll(HorizontalScrollbar, ScrollByPage, 100, 1);
- EXPECT_TRUE(scrollAnimator->hasRunningAnimation());
+ EXPECT_TRUE(scrollAnimator->hasAnimationThatRequiresService());
gMockedTime += 0.05;
- scrollAnimator->serviceScrollAnimations();
+ scrollAnimator->updateCompositorAnimations();
+ scrollAnimator->tickAnimation(getMockedTime());
EXPECT_NE(100, scrollAnimator->currentPosition().x());
EXPECT_NE(0, scrollAnimator->currentPosition().x());
@@ -142,25 +146,27 @@ TEST(ScrollAnimatorTest, Enabled)
reset(*scrollAnimator);
scrollAnimator->userScroll(HorizontalScrollbar, ScrollByPixel, 4, 25);
- EXPECT_TRUE(scrollAnimator->hasRunningAnimation());
+ EXPECT_TRUE(scrollAnimator->hasAnimationThatRequiresService());
gMockedTime += 0.05;
- scrollAnimator->serviceScrollAnimations();
+ scrollAnimator->updateCompositorAnimations();
+ scrollAnimator->tickAnimation(getMockedTime());
EXPECT_NE(100, scrollAnimator->currentPosition().x());
EXPECT_NE(0, scrollAnimator->currentPosition().x());
EXPECT_EQ(0, scrollAnimator->currentPosition().y());
gMockedTime += 1.0;
- scrollAnimator->serviceScrollAnimations();
+ scrollAnimator->updateCompositorAnimations();
+ scrollAnimator->tickAnimation(getMockedTime());
- EXPECT_FALSE(scrollAnimator->hasRunningAnimation());
+ EXPECT_FALSE(scrollAnimator->hasAnimationThatRequiresService());
EXPECT_EQ(100, scrollAnimator->currentPosition().x());
reset(*scrollAnimator);
scrollAnimator->userScroll(HorizontalScrollbar, ScrollByPrecisePixel, 4, 25);
- EXPECT_FALSE(scrollAnimator->hasRunningAnimation());
+ EXPECT_FALSE(scrollAnimator->hasAnimationThatRequiresService());
EXPECT_EQ(100, scrollAnimator->currentPosition().x());
EXPECT_NE(0, scrollAnimator->currentPosition().x());
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollableArea.cpp b/third_party/WebKit/Source/platform/scroll/ScrollableArea.cpp
index fb93af9..365aa95 100644
--- a/third_party/WebKit/Source/platform/scroll/ScrollableArea.cpp
+++ b/third_party/WebKit/Source/platform/scroll/ScrollableArea.cpp
@@ -453,6 +453,8 @@ void ScrollableArea::layerForScrollingDidChange(WebCompositorAnimationTimeline*
{
if (ProgrammaticScrollAnimator* programmaticScrollAnimator = existingProgrammaticScrollAnimator())
programmaticScrollAnimator->layerForCompositedScrollingDidChange(timeline);
+ if (ScrollAnimatorBase* scrollAnimator = existingScrollAnimator())
+ scrollAnimator->layerForCompositedScrollingDidChange(timeline);
}
bool ScrollableArea::scheduleAnimation()
@@ -468,8 +470,8 @@ void ScrollableArea::serviceScrollAnimations(double monotonicTime)
{
bool requiresAnimationService = false;
if (ScrollAnimatorBase* scrollAnimator = existingScrollAnimator()) {
- scrollAnimator->serviceScrollAnimations();
- if (scrollAnimator->hasRunningAnimation())
+ scrollAnimator->tickAnimation(monotonicTime);
+ if (scrollAnimator->hasAnimationThatRequiresService())
requiresAnimationService = true;
}
if (ProgrammaticScrollAnimator* programmaticScrollAnimator = existingProgrammaticScrollAnimator()) {
@@ -485,18 +487,24 @@ void ScrollableArea::updateCompositorScrollAnimations()
{
if (ProgrammaticScrollAnimator* programmaticScrollAnimator = existingProgrammaticScrollAnimator())
programmaticScrollAnimator->updateCompositorAnimations();
+
+ if (ScrollAnimatorBase* scrollAnimator = existingScrollAnimator())
+ scrollAnimator->updateCompositorAnimations();
}
void ScrollableArea::notifyCompositorAnimationFinished(int groupId)
{
if (ProgrammaticScrollAnimator* programmaticScrollAnimator = existingProgrammaticScrollAnimator())
programmaticScrollAnimator->notifyCompositorAnimationFinished(groupId);
+
+ if (ScrollAnimatorBase* scrollAnimator = existingScrollAnimator())
+ scrollAnimator->notifyCompositorAnimationFinished(groupId);
}
void ScrollableArea::cancelScrollAnimation()
{
if (ScrollAnimatorBase* scrollAnimator = existingScrollAnimator())
- scrollAnimator->cancelAnimations();
+ scrollAnimator->cancelAnimation();
}
void ScrollableArea::cancelProgrammaticScrollAnimation()
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollableArea.h b/third_party/WebKit/Source/platform/scroll/ScrollableArea.h
index 71e221b..50d99bf 100644
--- a/third_party/WebKit/Source/platform/scroll/ScrollableArea.h
+++ b/third_party/WebKit/Source/platform/scroll/ScrollableArea.h
@@ -212,7 +212,7 @@ public:
// Let subclasses provide a way of asking for and servicing scroll
// animations.
- bool scheduleAnimation();
+ virtual bool scheduleAnimation();
virtual void serviceScrollAnimations(double monotonicTime);
virtual void updateCompositorScrollAnimations();
virtual void registerForAnimation() { }