diff options
Diffstat (limited to 'third_party/WebKit/Source')
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() { } |