Changeset 285787 in webkit
- Timestamp:
- Nov 13, 2021, 11:37:36 PM (5 years ago)
- Location:
- trunk
- Files:
-
- 4 added
- 12 edited
-
LayoutTests/ChangeLog (modified) (1 diff)
-
LayoutTests/fast/scrolling/mac/momentum-animator-expected.txt (added)
-
LayoutTests/fast/scrolling/mac/momentum-animator-in-overflow-expected.txt (added)
-
LayoutTests/fast/scrolling/mac/momentum-animator-in-overflow.html (added)
-
LayoutTests/fast/scrolling/mac/momentum-animator.html (added)
-
Source/WTF/ChangeLog (modified) (1 diff)
-
Source/WTF/Scripts/Preferences/WebPreferencesInternal.yaml (modified) (1 diff)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/page/WheelEventDeltaFilter.cpp (modified) (1 diff)
-
Source/WebCore/page/WheelEventDeltaFilter.h (modified) (1 diff)
-
Source/WebCore/platform/PlatformWheelEvent.cpp (modified) (1 diff)
-
Source/WebCore/platform/ScrollAnimationMomentum.cpp (modified) (3 diffs)
-
Source/WebCore/platform/ScrollAnimationMomentum.h (modified) (1 diff)
-
Source/WebCore/platform/ScrollingEffectsController.cpp (modified) (3 diffs)
-
Source/WebCore/platform/ScrollingEffectsController.h (modified) (4 diffs)
-
Source/WebCore/platform/mac/ScrollingEffectsController.mm (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r285785 r285787 1 2021-11-13 Simon Fraser <simon.fraser@apple.com> 2 3 Run a ScrollAnimationMomentum for the momentum phase of a scroll 4 https://bugs.webkit.org/show_bug.cgi?id=232897 5 6 Reviewed by Tim Horton. 7 8 Some tests that enable the momentum animator. 9 10 * fast/scrolling/mac/momentum-animator-expected.txt: Added. 11 * fast/scrolling/mac/momentum-animator-in-overflow-expected.txt: Added. 12 * fast/scrolling/mac/momentum-animator-in-overflow.html: Added. 13 * fast/scrolling/mac/momentum-animator.html: Added. 14 1 15 2021-11-13 Said Abou-Hallawa <said@apple.com> 2 16 -
trunk/Source/WTF/ChangeLog
r285731 r285787 1 2021-11-13 Simon Fraser <simon.fraser@apple.com> 2 3 Run a ScrollAnimationMomentum for the momentum phase of a scroll 4 https://bugs.webkit.org/show_bug.cgi?id=232897 5 6 Reviewed by Tim Horton. 7 8 Set the MomentumScrollingAnimatorEnabled internal setting to off by default 9 while we bring up tests. 10 11 * Scripts/Preferences/WebPreferencesInternal.yaml: 12 1 13 2021-11-12 Chris Dumez <cdumez@apple.com> 2 14 -
trunk/Source/WTF/Scripts/Preferences/WebPreferencesInternal.yaml
r285549 r285787 543 543 defaultValue: 544 544 WebKitLegacy: 545 "PLATFORM(MAC)": true 546 default: false 547 WebKit: 548 "PLATFORM(MAC)": true 549 default: false 550 WebCore: 551 "PLATFORM(MAC)": true 545 default: false 546 WebKit: 547 default: false 548 WebCore: 552 549 default: false 553 550 -
trunk/Source/WebCore/ChangeLog
r285786 r285787 1 2021-11-13 Simon Fraser <simon.fraser@apple.com> 2 3 Run a ScrollAnimationMomentum for the momentum phase of a scroll 4 https://bugs.webkit.org/show_bug.cgi?id=232897 5 6 Reviewed by Tim Horton. 7 8 Run an animation for the momentum phase of a scroll, rather than scrolling in response 9 to wheel events, because it produces a smoother result with fewer dropped frames. 10 11 We re-use ScrollAnimationMomentum which is already used for scroll snap, but have to 12 allow it to yield unclamped coordinates, since using it for momentum can result in 13 rubber-banding. 14 15 When we get the momentum "began" event, we start the ScrollAnimationMomentum 16 using initial velocity computed from WheelEventDeltaFilter. ScrollingEffectsController then 17 ignores the reset of the momentum "changed" events. 18 19 We have to stop this animation when we receive a "begin" or "mayBegin" event, since 20 this indicates that the user has put fingers down on the trackpad. 21 22 Rename m_dragEndedScrollingVelocity to m_scrollingVelocityForScrollSnap for clarity 23 (at some point we should merge this with m_scrollingVelocityForMomentumAnimation). 24 25 Tests: fast/scrolling/mac/momentum-animator-in-overflow.html 26 fast/scrolling/mac/momentum-animator.html 27 28 * page/WheelEventDeltaFilter.cpp: 29 (WebCore::WheelEventDeltaFilter::shouldApplyFilteringForEvent): 30 * page/WheelEventDeltaFilter.h: 31 * platform/PlatformWheelEvent.cpp: 32 (WebCore::operator<<): 33 * platform/ScrollAnimationMomentum.cpp: 34 (WebCore::ScrollAnimationMomentum::startAnimatedScrollWithInitialVelocity): 35 (WebCore::ScrollAnimationMomentum::stop): 36 (WebCore::ScrollAnimationMomentum::serviceAnimation): 37 * platform/ScrollAnimationMomentum.h: 38 * platform/ScrollingEffectsController.cpp: 39 (WebCore::ScrollingEffectsController::ScrollingEffectsController): 40 (WebCore::ScrollingEffectsController::stopAnimatedNonRubberbandingScroll): 41 (WebCore::ScrollingEffectsController::startMomentumScrollWithInitialVelocity): 42 * platform/ScrollingEffectsController.h: 43 (WebCore::ScrollingEffectsController::momentumScrollingAnimatorEnabled const): 44 * platform/mac/ScrollingEffectsController.mm: 45 (WebCore::phaseToString): 46 (WebCore::ScrollingEffectsController::handleWheelEvent): 47 (WebCore::ScrollingEffectsController::startRubberBandAnimation): 48 (WebCore::ScrollingEffectsController::startRubberBandAnimationIfNecessary): 49 (WebCore::ScrollingEffectsController::processWheelEventForScrollSnap): 50 1 51 2021-11-13 Tim Horton <timothy_horton@apple.com> 2 52 -
trunk/Source/WebCore/page/WheelEventDeltaFilter.cpp
r285375 r285787 55 55 #if ENABLE(KINETIC_SCROLLING) 56 56 // Maybe it's a per-platform decision about which event phases get filtered. Ideally we'd filter momentum events too (but that breaks some diagonal scrolling cases). 57 // Also, ScrollingEffectsController should ask WheelEventDeltaFilter directly for the filtered velocity, rather than sending the velocity via PlatformWheelEvent. 57 58 auto phase = event.phase(); 58 59 return phase == PlatformWheelEventPhase::Began || phase == PlatformWheelEventPhase::Changed; -
trunk/Source/WebCore/page/WheelEventDeltaFilter.h
r285375 r285787 63 63 private: 64 64 std::optional<ScrollEventAxis> dominantAxis() const; 65 65 66 66 void reset(); 67 67 void updateWithDelta(FloatSize); -
trunk/Source/WebCore/platform/PlatformWheelEvent.cpp
r277772 r285787 109 109 ts << " phase \"" << event.phase() << "\" momentum phase \"" << event.momentumPhase() << "\""; 110 110 #endif 111 ts << " velocity " << event.scrollingVelocity(); 111 112 112 113 return ts; -
trunk/Source/WebCore/platform/ScrollAnimationMomentum.cpp
r285387 r285787 56 56 } 57 57 58 LOG(ScrollAnimations, "ScrollAnimationMomentum::startAnimatedScrollWithInitialVelocity: velocity %.2f,%.2f from %.2f,%.2f to %.2f,%.2f", 59 initialVelocity.width(), initialVelocity.height(), initialOffset.x(), initialOffset.y(), destinationScrollOffset.x(), destinationScrollOffset.y()); 60 58 61 if (destinationScrollOffset == initialOffset) { 59 62 m_momentumCalculator = nullptr; … … 82 85 void ScrollAnimationMomentum::stop() 83 86 { 87 LOG(ScrollAnimations, "ScrollAnimationMomentum::stop: offset %.2f,%.2f", m_currentOffset.x(), m_currentOffset.y()); 88 84 89 m_momentumCalculator = nullptr; 85 90 ScrollAnimation::stop(); … … 98 103 99 104 m_client.scrollAnimationDidUpdate(*this, m_currentOffset); 105 106 LOG(ScrollAnimations, "ScrollAnimationMomentum::serviceAnimation: offset %.2f,%.2f complete %d", m_currentOffset.x(), m_currentOffset.y(), animationComplete); 100 107 101 108 if (animationComplete) -
trunk/Source/WebCore/platform/ScrollAnimationMomentum.h
r285387 r285787 43 43 44 44 private: 45 ScrollClamping clamping() const final { return ScrollClamping::Unclamped; } 45 46 String debugDescription() const final; 46 47 -
trunk/Source/WebCore/platform/ScrollingEffectsController.cpp
r285387 r285787 50 50 ScrollingEffectsController::ScrollingEffectsController(ScrollingEffectsControllerClient& client) 51 51 : m_client(client) 52 , m_momentumScrollingAnimatorEnabled(client.momentumScrollingAnimatorEnabled()) 52 53 { 53 54 } … … 132 133 } 133 134 135 void ScrollingEffectsController::stopAnimatedNonRubberbandingScroll() 136 { 137 LOG_WITH_STREAM(ScrollAnimations, stream << "ScrollingEffectsController " << this << " stopAnimatedNonRubberbandingScroll"); 138 139 if (!m_currentAnimation) 140 return; 141 142 #if HAVE(RUBBER_BANDING) 143 if (is<ScrollAnimationRubberBand>(m_currentAnimation)) 144 return; 145 #endif 146 147 if (is<ScrollAnimationMomentum>(m_currentAnimation)) { 148 // If the animation is currently triggering rubberbanding, let it run. Ideally we'd check if the animation will cause rubberbanding at any time in the future. 149 auto currentOffset = m_currentAnimation->currentOffset(); 150 auto extents = m_client.scrollExtents(); 151 auto constrainedOffset = currentOffset.constrainedBetween(extents.minimumScrollOffset(), extents.maximumScrollOffset()); 152 if (currentOffset != constrainedOffset) 153 return; 154 } 155 156 m_currentAnimation->stop(); 157 } 158 134 159 void ScrollingEffectsController::stopAnimatedScroll() 135 160 { … … 152 177 153 178 bool started = downcast<ScrollAnimationMomentum>(*m_currentAnimation).startAnimatedScrollWithInitialVelocity(initialOffset, initialVelocity, initialDelta, destinationModifier); 154 LOG_WITH_STREAM(ScrollAnimations, stream << "ScrollingEffectsController::startMomentumScrollWithInitialVelocity() - animation " << *m_currentAnimation << " started " << started);179 LOG_WITH_STREAM(ScrollAnimations, stream << "ScrollingEffectsController::startMomentumScrollWithInitialVelocity() - animation " << *m_currentAnimation << " initialVelocity " << initialVelocity << " initialDelta " << initialDelta << " started " << started); 155 180 return started; 156 181 } -
trunk/Source/WebCore/platform/ScrollingEffectsController.h
r285526 r285787 139 139 bool retargetAnimatedScroll(FloatPoint newDestinationOffset); 140 140 bool retargetAnimatedScrollBy(FloatSize); 141 141 142 void stopAnimatedScroll(); 143 void stopAnimatedNonRubberbandingScroll(); 142 144 143 145 void stopKeyboardScrolling(); … … 222 224 void startOrStopAnimationCallbacks(); 223 225 226 bool momentumScrollingAnimatorEnabled() const { return m_momentumScrollingAnimatorEnabled; } 227 224 228 // ScrollAnimationClient 225 229 void scrollAnimationDidUpdate(ScrollAnimation&, const FloatPoint& /* currentOffset */) final; … … 249 253 bool m_isAnimatingKeyboardScrolling { false }; 250 254 bool m_inScrollGesture { false }; 255 bool m_momentumScrollingAnimatorEnabled { false }; 251 256 252 257 #if PLATFORM(MAC) … … 256 261 FloatSize m_momentumVelocity; 257 262 263 FloatSize m_scrollingVelocityForMomentumAnimation; // Do we need both this, m_scrollingVelocityForScrollSnap and m_momentumVelocity? 264 FloatSize m_scrollingVelocityForScrollSnap; 265 #if !LOG_DISABLED 266 FloatPoint m_eventDrivenScrollOffset; 267 #endif 268 258 269 bool m_momentumScrollInProgress { false }; 259 270 bool m_ignoreMomentumScrolls { false }; 260 271 bool m_isRubberBanding { false }; 261 272 262 FloatSize m_dragEndedScrollingVelocity;263 273 std::unique_ptr<ScrollingEffectsControllerTimer> m_statelessSnapTransitionTimer; 264 274 -
trunk/Source/WebCore/platform/mac/ScrollingEffectsController.mm
r285387 r285787 31 31 #import "ScrollAnimationRubberBand.h" 32 32 #import "ScrollExtents.h" 33 #import "WheelEventDeltaFilter.h" 33 34 #import "WheelEventTestMonitor.h" 34 35 #import <pal/spi/mac/NSScrollViewSPI.h> … … 111 112 } 112 113 114 #if !LOG_DISABLED 115 static const char* phaseToString(PlatformWheelEventPhase phase) 116 { 117 switch (phase) { 118 case PlatformWheelEventPhase::None: return "none"; 119 case PlatformWheelEventPhase::Began: return "began"; 120 case PlatformWheelEventPhase::Stationary: return "stationary"; 121 case PlatformWheelEventPhase::Changed: return "changed"; 122 case PlatformWheelEventPhase::Ended: return "ended"; 123 case PlatformWheelEventPhase::Cancelled: return "cancelled"; 124 case PlatformWheelEventPhase::MayBegin: return "mayBegin"; 125 } 126 return ""; 127 } 128 #endif 129 113 130 bool ScrollingEffectsController::handleWheelEvent(const PlatformWheelEvent& wheelEvent) 114 131 { 132 if (WheelEventDeltaFilter::shouldApplyFilteringForEvent(wheelEvent)) 133 m_scrollingVelocityForMomentumAnimation = -wheelEvent.scrollingVelocity(); // Note that event delta is reversed from scroll direction. 134 115 135 if (processWheelEventForScrollSnap(wheelEvent)) 116 136 return true; 117 137 118 if (wheelEvent.phase() == PlatformWheelEventPhase::MayBegin || wheelEvent.phase() == PlatformWheelEventPhase::Cancelled) 119 return false; 138 if (wheelEvent.phase() == PlatformWheelEventPhase::MayBegin || wheelEvent.phase() == PlatformWheelEventPhase::Cancelled) { 139 if (momentumScrollingAnimatorEnabled()) { 140 LOG(ScrollAnimations, "Event (%s, %s): stopping animated scroll", phaseToString(wheelEvent.phase()), phaseToString(wheelEvent.momentumPhase())); 141 stopAnimatedScroll(); 142 } 143 return false; 144 } 120 145 121 146 if (wheelEvent.phase() == PlatformWheelEventPhase::Began) { 147 if (momentumScrollingAnimatorEnabled()) { 148 LOG(ScrollAnimations, "Event (%s, %s): stopping animated scroll", phaseToString(wheelEvent.phase()), phaseToString(wheelEvent.momentumPhase())); 149 stopAnimatedScroll(); 150 } 151 122 152 // FIXME: Trying to decide if a gesture is horizontal or vertical at the "began" phase is very error-prone. 123 153 auto horizontalSide = ScrollableArea::targetSideForScrollDelta(-wheelEvent.delta(), ScrollEventAxis::Horizontal); … … 178 208 179 209 auto momentumPhase = wheelEvent.momentumPhase(); 180 if (!m_momentumScrollInProgress && (momentumPhase == PlatformWheelEventPhase::Began || momentumPhase == PlatformWheelEventPhase::Changed)) 210 if (!m_momentumScrollInProgress && (momentumPhase == PlatformWheelEventPhase::Began || momentumPhase == PlatformWheelEventPhase::Changed)) { 181 211 m_momentumScrollInProgress = true; 212 if (momentumScrollingAnimatorEnabled()) { 213 startMomentumScrollWithInitialVelocity(m_client.scrollOffset(), m_scrollingVelocityForMomentumAnimation, -wheelEvent.delta(), [](const FloatPoint& targetOffset) { return targetOffset; }); 214 #if !LOG_DISABLED 215 m_eventDrivenScrollOffset = m_client.scrollOffset(); 216 #endif 217 } 218 } 219 220 if (momentumPhase == PlatformWheelEventPhase::Changed && momentumScrollingAnimatorEnabled()) { 221 #if !LOG_DISABLED 222 m_eventDrivenScrollOffset -= wheelEvent.delta(); 223 #endif 224 LOG(ScrollAnimations, "Event (%s, %s): ignoring - would have scrolled to %.2f,%.2f", phaseToString(wheelEvent.phase()), phaseToString(wheelEvent.momentumPhase()), 225 m_eventDrivenScrollOffset.x(), m_eventDrivenScrollOffset.y()); 226 return true; 227 } 182 228 183 229 bool shouldStretch = false; … … 394 440 bool ScrollingEffectsController::startRubberBandAnimation(const FloatPoint& targetOffset, const FloatSize& initialVelocity, const FloatSize& initialOverscroll) 395 441 { 442 if (is<ScrollAnimationMomentum>(m_currentAnimation) && m_currentAnimation->isActive()) { 443 LOG_WITH_STREAM(ScrollAnimations, stream << "ScrollingEffectsController::startRubberBandAnimation() - momentum animation is present"); 444 return false; 445 } 446 396 447 if (m_currentAnimation) 397 448 m_currentAnimation->stop(); … … 440 491 441 492 auto stretchAmount = m_client.stretchAmount(); 442 443 LOG_WITH_STREAM(ScrollAnimations, stream << "ScrollingEffectsController::startRubberBandAnimationIfNecessary() - rubberBandAnimationRunning " << m_isAnimatingRubberBand << " stretchAmount " << stretchAmount << " targetOffset " << targetOffset);444 445 493 if (stretchAmount.isZero() && !willOverscroll) 446 494 return; … … 460 508 initialVelocity.setHeight(0); 461 509 510 LOG_WITH_STREAM(ScrollAnimations, stream << "ScrollingEffectsController::startRubberBandAnimationIfNecessary() - rubberBandAnimationRunning " << m_isAnimatingRubberBand << " stretchAmount " << stretchAmount << " contrainedOffset " << contrainedOffset << " initialVelocity " << initialVelocity); 462 511 startRubberBandAnimation(contrainedOffset, initialVelocity, stretchAmount); 463 512 } … … 636 685 stopScrollSnapAnimation(); 637 686 m_scrollSnapState->transitionToUserInteractionState(); 638 m_ dragEndedScrollingVelocity= -wheelEvent.scrollingVelocity();687 m_scrollingVelocityForScrollSnap = -wheelEvent.scrollingVelocity(); 639 688 break; 640 689 case WheelEventStatus::UserScrollEnd: … … 643 692 break; 644 693 case WheelEventStatus::MomentumScrollBegin: 645 if (m_scrollSnapState->transitionToGlideAnimationState(m_client.scrollExtents(), m_client.pageScaleFactor(), m_client.scrollOffset(), m_ dragEndedScrollingVelocity, FloatSize(-wheelEvent.deltaX(), -wheelEvent.deltaY()))) {694 if (m_scrollSnapState->transitionToGlideAnimationState(m_client.scrollExtents(), m_client.pageScaleFactor(), m_client.scrollOffset(), m_scrollingVelocityForScrollSnap, -wheelEvent.delta())) { 646 695 startScrollSnapAnimation(); 647 696 isMomentumScrolling = true; 648 697 } 649 m_ dragEndedScrollingVelocity= { };698 m_scrollingVelocityForScrollSnap = { }; 650 699 break; 651 700 case WheelEventStatus::MomentumScrolling:
Note:
See TracChangeset
for help on using the changeset viewer.