1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef mozilla_layers_AsyncPanZoomController_h 8 #define mozilla_layers_AsyncPanZoomController_h 9 10 #include "mozilla/ipc/CrossProcessMutex.h" 11 #include "mozilla/layers/GeckoContentController.h" 12 #include "mozilla/layers/RepaintRequest.h" 13 #include "mozilla/layers/SampleTime.h" 14 #include "mozilla/layers/ZoomConstraints.h" 15 #include "mozilla/Atomics.h" 16 #include "mozilla/Attributes.h" 17 #include "mozilla/EventForwards.h" 18 #include "mozilla/Monitor.h" 19 #include "mozilla/RecursiveMutex.h" 20 #include "mozilla/RefPtr.h" 21 #include "mozilla/ScrollTypes.h" 22 #include "mozilla/StaticPrefs_apz.h" 23 #include "mozilla/UniquePtr.h" 24 #include "InputData.h" 25 #include "Axis.h" // for Axis, Side, etc. 26 #include "ExpectedGeckoMetrics.h" 27 #include "FlingAccelerator.h" 28 #include "InputQueue.h" 29 #include "APZUtils.h" 30 #include "Layers.h" // for Layer::ScrollDirection 31 #include "LayersTypes.h" 32 #include "mozilla/gfx/Matrix.h" 33 #include "nsRegion.h" 34 #include "nsTArray.h" 35 #include "PotentialCheckerboardDurationTracker.h" 36 #include "RecentEventsBuffer.h" // for RecentEventsBuffer 37 #include "SampledAPZCState.h" 38 39 namespace mozilla { 40 41 namespace ipc { 42 43 class SharedMemoryBasic; 44 45 } // namespace ipc 46 47 namespace layers { 48 49 class AsyncDragMetrics; 50 class APZCTreeManager; 51 struct ScrollableLayerGuid; 52 class CompositorController; 53 class MetricsSharingController; 54 class GestureEventListener; 55 struct AsyncTransform; 56 class AsyncPanZoomAnimation; 57 class StackScrollerFlingAnimation; 58 template <typename FlingPhysics> 59 class GenericFlingAnimation; 60 class AndroidFlingPhysics; 61 class DesktopFlingPhysics; 62 class InputBlockState; 63 struct FlingHandoffState; 64 class TouchBlockState; 65 class PanGestureBlockState; 66 class OverscrollHandoffChain; 67 struct OverscrollHandoffState; 68 class StateChangeNotificationBlocker; 69 class CheckerboardEvent; 70 class OverscrollEffectBase; 71 class WidgetOverscrollEffect; 72 class GenericOverscrollEffect; 73 class AndroidSpecificState; 74 struct KeyboardScrollAction; 75 struct ZoomTarget; 76 77 namespace apz { 78 struct AsyncScrollThumbTransformer; 79 } 80 81 // Base class for grouping platform-specific APZC state variables. 82 class PlatformSpecificStateBase { 83 public: 84 virtual ~PlatformSpecificStateBase() = default; AsAndroidSpecificState()85 virtual AndroidSpecificState* AsAndroidSpecificState() { return nullptr; } 86 // PLPPI = "ParentLayer pixels per (Screen) inch" 87 virtual AsyncPanZoomAnimation* CreateFlingAnimation( 88 AsyncPanZoomController& aApzc, const FlingHandoffState& aHandoffState, 89 float aPLPPI); 90 virtual UniquePtr<VelocityTracker> CreateVelocityTracker(Axis* aAxis); 91 InitializeGlobalState()92 static void InitializeGlobalState() {} 93 }; 94 95 /* 96 * Represents a transform from the ParentLayer coordinate space of an APZC 97 * to the ParentLayer coordinate space of its parent APZC. 98 * Each layer along the way contributes to the transform. We track 99 * contributions that are perspective transforms separately, as sometimes 100 * these require special handling. 101 */ 102 struct AncestorTransform { 103 gfx::Matrix4x4 mTransform; 104 gfx::Matrix4x4 mPerspectiveTransform; 105 106 AncestorTransform() = default; 107 AncestorTransformAncestorTransform108 AncestorTransform(const gfx::Matrix4x4& aTransform, 109 bool aTransformIsPerspective) { 110 (aTransformIsPerspective ? mPerspectiveTransform : mTransform) = aTransform; 111 } 112 AncestorTransformAncestorTransform113 AncestorTransform(const gfx::Matrix4x4& aTransform, 114 const gfx::Matrix4x4& aPerspectiveTransform) 115 : mTransform(aTransform), mPerspectiveTransform(aPerspectiveTransform) {} 116 CombinedTransformAncestorTransform117 gfx::Matrix4x4 CombinedTransform() const { 118 return mTransform * mPerspectiveTransform; 119 } 120 ContainsPerspectiveTransformAncestorTransform121 bool ContainsPerspectiveTransform() const { 122 return !mPerspectiveTransform.IsIdentity(); 123 } 124 GetPerspectiveTransformAncestorTransform125 gfx::Matrix4x4 GetPerspectiveTransform() const { 126 return mPerspectiveTransform; 127 } 128 129 friend AncestorTransform operator*(const AncestorTransform& aA, 130 const AncestorTransform& aB) { 131 return AncestorTransform{ 132 aA.mTransform * aB.mTransform, 133 aA.mPerspectiveTransform * aB.mPerspectiveTransform}; 134 } 135 }; 136 137 /** 138 * Controller for all panning and zooming logic. Any time a user input is 139 * detected and it must be processed in some way to affect what the user sees, 140 * it goes through here. Listens for any input event from InputData and can 141 * optionally handle WidgetGUIEvent-derived touch events, but this must be done 142 * on the main thread. Note that this class completely cross-platform. 143 * 144 * Input events originate on the UI thread of the platform that this runs on, 145 * and are then sent to this class. This class processes the event in some way; 146 * for example, a touch move will usually lead to a panning of content (though 147 * of course there are exceptions, such as if content preventDefaults the event, 148 * or if the target frame is not scrollable). The compositor interacts with this 149 * class by locking it and querying it for the current transform matrix based on 150 * the panning and zooming logic that was invoked on the UI thread. 151 * 152 * Currently, each outer DOM window (i.e. a website in a tab, but not any 153 * subframes) has its own AsyncPanZoomController. In the future, to support 154 * asynchronously scrolled subframes, we want to have one AsyncPanZoomController 155 * per frame. 156 */ 157 class AsyncPanZoomController { 158 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AsyncPanZoomController) 159 160 typedef mozilla::MonitorAutoLock MonitorAutoLock; 161 typedef mozilla::gfx::Matrix4x4 Matrix4x4; 162 typedef mozilla::layers::RepaintRequest::ScrollOffsetUpdateType 163 RepaintUpdateType; 164 165 public: 166 enum GestureBehavior { 167 // The platform code is responsible for forwarding gesture events here. We 168 // will not attempt to generate gesture events from MultiTouchInputs. 169 DEFAULT_GESTURES, 170 // An instance of GestureEventListener is used to detect gestures. This is 171 // handled completely internally within this class. 172 USE_GESTURE_DETECTOR 173 }; 174 175 /** 176 * Gets the DPI from the tree manager. 177 */ 178 float GetDPI() const; 179 180 /** 181 * Constant describing the tolerance in distance we use, multiplied by the 182 * device DPI, before we start panning the screen. This is to prevent us from 183 * accidentally processing taps as touch moves, and from very short/accidental 184 * touches moving the screen. 185 * Note: It's an abuse of the 'Coord' class to use it to represent a 2D 186 * distance, but it's the closest thing we currently have. 187 */ 188 ScreenCoord GetTouchStartTolerance() const; 189 /** 190 * Same as GetTouchStartTolerance, but the tolerance for how far the touch 191 * has to move before it starts allowing touchmove events to be dispatched 192 * to content, for non-scrollable content. 193 */ 194 ScreenCoord GetTouchMoveTolerance() const; 195 /** 196 * Same as GetTouchStartTolerance, but the tolerance for how close the second 197 * tap has to be to the first tap in order to be counted as part of a 198 * multi-tap gesture (double-tap or one-touch-pinch). 199 */ 200 ScreenCoord GetSecondTapTolerance() const; 201 202 AsyncPanZoomController(LayersId aLayersId, APZCTreeManager* aTreeManager, 203 const RefPtr<InputQueue>& aInputQueue, 204 GeckoContentController* aController, 205 GestureBehavior aGestures = DEFAULT_GESTURES); 206 207 // -------------------------------------------------------------------------- 208 // These methods must only be called on the gecko thread. 209 // 210 211 /** 212 * Read the various prefs and do any global initialization for all APZC 213 * instances. This must be run on the gecko thread before any APZC instances 214 * are actually used for anything meaningful. 215 */ 216 static void InitializeGlobalState(); 217 218 // -------------------------------------------------------------------------- 219 // These methods must only be called on the controller/UI thread. 220 // 221 222 /** 223 * Kicks an animation to zoom to a rect. This may be either a zoom out or zoom 224 * in. The actual animation is done on the sampler thread after being set 225 * up. 226 */ 227 void ZoomToRect(const ZoomTarget& aZoomTarget, const uint32_t aFlags); 228 229 /** 230 * Updates any zoom constraints contained in the <meta name="viewport"> tag. 231 */ 232 void UpdateZoomConstraints(const ZoomConstraints& aConstraints); 233 234 /** 235 * Schedules a runnable to run on the controller/UI thread at some time 236 * in the future. 237 */ 238 void PostDelayedTask(already_AddRefed<Runnable> aTask, int aDelayMs); 239 240 // -------------------------------------------------------------------------- 241 // These methods must only be called on the sampler thread. 242 // 243 244 /** 245 * Advances any animations currently running to the given timestamp. 246 * This may be called multiple times with the same timestamp. 247 * 248 * The return value indicates whether or not any currently running animation 249 * should continue. If true, the compositor should schedule another composite. 250 */ 251 bool AdvanceAnimations(const SampleTime& aSampleTime); 252 253 bool UpdateAnimation(const RecursiveMutexAutoLock& aProofOfLock, 254 const SampleTime& aSampleTime, 255 nsTArray<RefPtr<Runnable>>* aOutDeferredTasks); 256 257 // -------------------------------------------------------------------------- 258 // These methods must only be called on the updater thread. 259 // 260 261 /** 262 * A shadow layer update has arrived. |aScrollMetdata| is the new 263 * ScrollMetadata for the container layer corresponding to this APZC. 264 * |aIsFirstPaint| is a flag passed from the shadow 265 * layers code indicating that the scroll metadata being sent with this call 266 * are the initial metadata and the initial paint of the frame has just 267 * happened. 268 */ 269 void NotifyLayersUpdated(const ScrollMetadata& aScrollMetadata, 270 bool aIsFirstPaint, bool aThisLayerTreeUpdated); 271 272 /** 273 * The platform implementation must set the compositor controller so that we 274 * can request composites. 275 */ 276 void SetCompositorController(CompositorController* aCompositorController); 277 278 /** 279 * If we need to share the frame metrics with some other thread, this 280 * controller needs to be set and provides relevant information/APIs. 281 */ 282 void SetMetricsSharingController( 283 MetricsSharingController* aMetricsSharingController); 284 285 // -------------------------------------------------------------------------- 286 // These methods can be called from any thread. 287 // 288 289 /** 290 * Shut down the controller/UI thread state and prepare to be 291 * deleted (which may happen from any thread). 292 */ 293 void Destroy(); 294 295 /** 296 * Returns true if Destroy() has already been called on this APZC instance. 297 */ 298 bool IsDestroyed() const; 299 300 /** 301 * Returns the transform to take something from the coordinate space of the 302 * last thing we know gecko painted, to the coordinate space of the last thing 303 * we asked gecko to paint. In cases where that last request has not yet been 304 * processed, this is needed to transform input events properly into a space 305 * gecko will understand. 306 */ 307 Matrix4x4 GetTransformToLastDispatchedPaint() const; 308 309 /** 310 * Returns the number of CSS pixels of checkerboard according to the metrics 311 * in this APZC. The argument provided by the caller is the composition bounds 312 * of this APZC, additionally clipped by the composition bounds of any 313 * ancestor APZCs, accounting for all the async transforms. 314 */ 315 uint32_t GetCheckerboardMagnitude( 316 const ParentLayerRect& aClippedCompositionBounds) const; 317 318 /** 319 * Report the number of CSSPixel-milliseconds of checkerboard to telemetry. 320 * See GetCheckerboardMagnitude for documentation of the 321 * aClippedCompositionBounds argument that needs to be provided by the caller. 322 */ 323 void ReportCheckerboard(const SampleTime& aSampleTime, 324 const ParentLayerRect& aClippedCompositionBounds); 325 326 /** 327 * Flush any active checkerboard report that's in progress. This basically 328 * pretends like any in-progress checkerboard event has terminated, and pushes 329 * out the report to the checkerboard reporting service and telemetry. If the 330 * checkerboard event has not really finished, it will start a new event 331 * on the next composite. 332 */ 333 void FlushActiveCheckerboardReport(); 334 335 /** 336 * See documentation on corresponding method in APZPublicUtils.h 337 */ 338 static gfx::IntSize GetDisplayportAlignmentMultiplier( 339 const ScreenSize& aBaseSize); 340 341 enum class ZoomInProgress { 342 No, 343 Yes, 344 }; 345 346 /** 347 * Recalculates the displayport. Ideally, this should paint an area bigger 348 * than the composite-to dimensions so that when you scroll down, you don't 349 * checkerboard immediately. This includes a bunch of logic, including 350 * algorithms to bias painting in the direction of the velocity and other 351 * such things. 352 */ 353 static const ScreenMargin CalculatePendingDisplayPort( 354 const FrameMetrics& aFrameMetrics, const ParentLayerPoint& aVelocity, 355 ZoomInProgress aZoomInProgress); 356 357 nsEventStatus HandleDragEvent(const MouseInput& aEvent, 358 const AsyncDragMetrics& aDragMetrics, 359 CSSCoord aInitialThumbPos); 360 361 /** 362 * Handler for events which should not be intercepted by the touch listener. 363 */ 364 nsEventStatus HandleInputEvent( 365 const InputData& aEvent, 366 const ScreenToParentLayerMatrix4x4& aTransformToApzc); 367 368 /** 369 * Handler for gesture events. 370 * Currently some gestures are detected in GestureEventListener that calls 371 * APZC back through this handler in order to avoid recursive calls to 372 * APZC::HandleInputEvent() which is supposed to do the work for 373 * ReceiveInputEvent(). 374 */ 375 nsEventStatus HandleGestureEvent(const InputData& aEvent); 376 377 /** 378 * Start autoscrolling this APZC, anchored at the provided location. 379 */ 380 void StartAutoscroll(const ScreenPoint& aAnchorLocation); 381 382 /** 383 * Stop autoscrolling this APZC. 384 */ 385 void StopAutoscroll(); 386 387 /** 388 * Populates the provided object (if non-null) with the scrollable guid of 389 * this apzc. 390 */ 391 void GetGuid(ScrollableLayerGuid* aGuidOut) const; 392 393 /** 394 * Returns the scrollable guid of this apzc. 395 */ 396 ScrollableLayerGuid GetGuid() const; 397 398 /** 399 * Returns true if this APZC instance is for the layer identified by the guid. 400 */ 401 bool Matches(const ScrollableLayerGuid& aGuid); 402 403 /** 404 * Returns true if the tree manager of this APZC is the same as the one 405 * passed in. 406 */ 407 bool HasTreeManager(const APZCTreeManager* aTreeManager) const; 408 409 void StartAnimation(AsyncPanZoomAnimation* aAnimation); 410 411 /** 412 * Cancels any currently running animation. 413 * aFlags is a bit-field to provide specifics of how to cancel the animation. 414 * See CancelAnimationFlags. 415 */ 416 void CancelAnimation(CancelAnimationFlags aFlags = Default); 417 418 /** 419 * Clear any overscroll on this APZC. 420 */ 421 void ClearOverscroll(); 422 423 /** 424 * Returns whether this APZC is for an element marked with the 'scrollgrab' 425 * attribute. 426 */ HasScrollgrab()427 bool HasScrollgrab() const { return mScrollMetadata.GetHasScrollgrab(); } 428 429 /** 430 * Returns whether this APZC has scroll snap points. 431 */ HasScrollSnapping()432 bool HasScrollSnapping() const { 433 return mScrollMetadata.GetSnapInfo().HasScrollSnapping(); 434 } 435 436 /** 437 * Returns whether this APZC has room to be panned (in any direction). 438 */ 439 bool IsPannable() const; 440 441 /** 442 * Returns whether this APZC represents a scroll info layer. 443 */ 444 bool IsScrollInfoLayer() const; 445 446 /** 447 * Returns true if the APZC has been flung with a velocity greater than the 448 * stop-on-tap fling velocity threshold (which is pref-controlled). 449 */ 450 bool IsFlingingFast() const; 451 452 /** 453 * Returns whether this APZC is currently autoscrolling. 454 */ IsAutoscroll()455 bool IsAutoscroll() const { return mState == AUTOSCROLL; } 456 457 /** 458 * Returns the identifier of the touch in the last touch event processed by 459 * this APZC. This should only be called when the last touch event contained 460 * only one touch. 461 */ 462 int32_t GetLastTouchIdentifier() const; 463 464 /** 465 * Returns the matrix that transforms points from global screen space into 466 * this APZC's ParentLayer space. 467 * To respect the lock ordering, mRecursiveMutex must NOT be held when calling 468 * this function (since this function acquires the tree lock). 469 */ 470 ScreenToParentLayerMatrix4x4 GetTransformToThis() const; 471 472 /** 473 * Convert the vector |aVector|, rooted at the point |aAnchor|, from 474 * this APZC's ParentLayer coordinates into screen coordinates. 475 * The anchor is necessary because with 3D tranforms, the location of the 476 * vector can affect the result of the transform. 477 * To respect the lock ordering, mRecursiveMutex must NOT be held when calling 478 * this function (since this function acquires the tree lock). 479 */ 480 ScreenPoint ToScreenCoordinates(const ParentLayerPoint& aVector, 481 const ParentLayerPoint& aAnchor) const; 482 483 /** 484 * Convert the vector |aVector|, rooted at the point |aAnchor|, from 485 * screen coordinates into this APZC's ParentLayer coordinates. 486 * The anchor is necessary because with 3D tranforms, the location of the 487 * vector can affect the result of the transform. 488 * To respect the lock ordering, mRecursiveMutex must NOT be held when calling 489 * this function (since this function acquires the tree lock). 490 */ 491 ParentLayerPoint ToParentLayerCoordinates(const ScreenPoint& aVector, 492 const ScreenPoint& aAnchor) const; 493 494 /** 495 * Same as above, but uses an ExternalPoint as the anchor. 496 */ 497 ParentLayerPoint ToParentLayerCoordinates(const ScreenPoint& aVector, 498 const ExternalPoint& aAnchor) const; 499 500 /** 501 * Combines an offset defined as an external point, with a window-relative 502 * offset to give an absolute external point. 503 */ 504 static ExternalPoint ToExternalPoint(const ExternalPoint& aScreenOffset, 505 const ScreenPoint& aScreenPoint); 506 507 /** 508 * Gets a vector where the head is the given point, and the tail is 509 * the touch start position. 510 */ 511 ScreenPoint PanVector(const ExternalPoint& aPos) const; 512 513 // Return whether or not a wheel event will be able to scroll in either 514 // direction. 515 bool CanScroll(const InputData& aEvent) const; 516 517 // Return the directions in which this APZC allows handoff (as governed by 518 // overscroll-behavior). 519 ScrollDirections GetAllowedHandoffDirections() const; 520 521 // Return the directions in which this APZC allows overscrolling. 522 ScrollDirections GetOverscrollableDirections() const; 523 524 // Return whether or not a scroll delta will be able to scroll in either 525 // direction. 526 bool CanScroll(const ParentLayerPoint& aDelta) const; 527 528 // Return whether or not a scroll delta will be able to scroll in either 529 // direction with wheel. 530 bool CanScrollWithWheel(const ParentLayerPoint& aDelta) const; 531 532 // Return whether or not there is room to scroll this APZC 533 // in the given direction. 534 bool CanScroll(ScrollDirection aDirection) const; 535 536 // Return the directions in which this APZC is able to scroll. 537 SideBits ScrollableDirections() const; 538 539 // Return true if there is room to scroll along with moving the dynamic 540 // toolbar. 541 // 542 // NOTE: This function should be used only for the root content APZC. 543 bool CanVerticalScrollWithDynamicToolbar() const; 544 545 // Return true if there is room to scroll downwards. 546 bool CanScrollDownwards() const; 547 548 /** 549 * Convert a point on the scrollbar from this APZC's ParentLayer coordinates 550 * to CSS coordinates relative to the beginning of the scroll track. 551 * Only the component in the direction of scrolling is returned. 552 */ 553 CSSCoord ConvertScrollbarPoint(const ParentLayerPoint& aScrollbarPoint, 554 const ScrollbarData& aThumbData) const; 555 556 void NotifyMozMouseScrollEvent(const nsString& aString) const; 557 558 bool OverscrollBehaviorAllowsSwipe() const; 559 560 //|Metrics()| and |Metrics() const| are getter functions that both return 561 // mScrollMetadata.mMetrics 562 563 const FrameMetrics& Metrics() const; 564 FrameMetrics& Metrics(); 565 566 /** 567 * Get the GeckoViewMetrics to be sent to Gecko for the current composite. 568 */ 569 GeckoViewMetrics GetGeckoViewMetrics() const; 570 571 // Helper function to compare root frame metrics and update them 572 // Returns true when the metrics have changed and were updated. 573 bool UpdateRootFrameMetricsIfChanged(GeckoViewMetrics& aMetrics); 574 575 // Returns the cached current frame time. 576 SampleTime GetFrameTime() const; 577 578 private: 579 // Get whether the horizontal content of the honoured target of auto-dir 580 // scrolling starts from right to left. If you don't know of auto-dir 581 // scrolling or what a honoured target means, 582 // @see mozilla::WheelDeltaAdjustmentStrategy 583 bool IsContentOfHonouredTargetRightToLeft(bool aHonoursRoot) const; 584 585 protected: 586 // Protected destructor, to discourage deletion outside of Release(): 587 virtual ~AsyncPanZoomController(); 588 589 /** 590 * Helper method for touches beginning. Sets everything up for panning and any 591 * multitouch gestures. 592 */ 593 nsEventStatus OnTouchStart(const MultiTouchInput& aEvent); 594 595 /** 596 * Helper method for touches moving. Does any transforms needed when panning. 597 */ 598 nsEventStatus OnTouchMove(const MultiTouchInput& aEvent); 599 600 /** 601 * Helper method for touches ending. Redraws the screen if necessary and does 602 * any cleanup after a touch has ended. 603 */ 604 nsEventStatus OnTouchEnd(const MultiTouchInput& aEvent); 605 606 /** 607 * Helper method for touches being cancelled. Treated roughly the same as a 608 * touch ending (OnTouchEnd()). 609 */ 610 nsEventStatus OnTouchCancel(const MultiTouchInput& aEvent); 611 612 /** 613 * Helper method for scales beginning. Distinct from the OnTouch* handlers in 614 * that this implies some outside implementation has determined that the user 615 * is pinching. 616 */ 617 nsEventStatus OnScaleBegin(const PinchGestureInput& aEvent); 618 619 /** 620 * Helper method for scaling. As the user moves their fingers when pinching, 621 * this changes the scale of the page. 622 */ 623 nsEventStatus OnScale(const PinchGestureInput& aEvent); 624 625 /** 626 * Helper method for scales ending. Redraws the screen if necessary and does 627 * any cleanup after a scale has ended. 628 */ 629 nsEventStatus OnScaleEnd(const PinchGestureInput& aEvent); 630 631 /** 632 * Helper methods for handling pan events. 633 */ 634 nsEventStatus OnPanMayBegin(const PanGestureInput& aEvent); 635 nsEventStatus OnPanCancelled(const PanGestureInput& aEvent); 636 nsEventStatus OnPanBegin(const PanGestureInput& aEvent); 637 enum class FingersOnTouchpad { 638 Yes, 639 No, 640 }; 641 nsEventStatus OnPan(const PanGestureInput& aEvent, 642 FingersOnTouchpad aFingersOnTouchpad); 643 nsEventStatus OnPanEnd(const PanGestureInput& aEvent); 644 nsEventStatus OnPanMomentumStart(const PanGestureInput& aEvent); 645 nsEventStatus OnPanMomentumEnd(const PanGestureInput& aEvent); 646 nsEventStatus HandleEndOfPan(); 647 nsEventStatus OnPanInterrupted(const PanGestureInput& aEvent); 648 649 /** 650 * Helper methods for handling scroll wheel events. 651 */ 652 nsEventStatus OnScrollWheel(const ScrollWheelInput& aEvent); 653 654 /** 655 * Gets the scroll wheel delta's values in parent-layer pixels from the 656 * original delta's values of a wheel input. 657 */ 658 ParentLayerPoint GetScrollWheelDelta(const ScrollWheelInput& aEvent) const; 659 660 /** 661 * This function is like GetScrollWheelDelta(aEvent). 662 * The difference is the four added parameters provide values as alternatives 663 * to the original wheel input's delta values, so |aEvent|'s delta values are 664 * ignored in this function, we only use some other member variables and 665 * functions of |aEvent|. 666 */ 667 ParentLayerPoint GetScrollWheelDelta(const ScrollWheelInput& aEvent, 668 double aDeltaX, double aDeltaY, 669 double aMultiplierX, 670 double aMultiplierY) const; 671 672 /** 673 * This deleted function is used for: 674 * 1. avoiding accidental implicit value type conversions of input delta 675 * values when callers intend to call the above function; 676 * 2. decoupling the manual relationship between the delta value type and the 677 * above function. If by any chance the defined delta value type in 678 * ScrollWheelInput has changed, this will automatically result in build 679 * time failure, so we can learn of it the first time and accordingly 680 * redefine those parameters' value types in the above function. 681 */ 682 template <typename T> 683 ParentLayerPoint GetScrollWheelDelta(ScrollWheelInput&, T, T, T, T) = delete; 684 685 /** 686 * Helper methods for handling keyboard events. 687 */ 688 nsEventStatus OnKeyboard(const KeyboardInput& aEvent); 689 690 CSSPoint GetKeyboardDestination(const KeyboardScrollAction& aAction) const; 691 692 /** 693 * Helper methods for long press gestures. 694 */ 695 MOZ_CAN_RUN_SCRIPT_BOUNDARY 696 nsEventStatus OnLongPress(const TapGestureInput& aEvent); 697 nsEventStatus OnLongPressUp(const TapGestureInput& aEvent); 698 699 /** 700 * Helper method for single tap gestures. 701 */ 702 nsEventStatus OnSingleTapUp(const TapGestureInput& aEvent); 703 704 /** 705 * Helper method for a single tap confirmed. 706 */ 707 nsEventStatus OnSingleTapConfirmed(const TapGestureInput& aEvent); 708 709 /** 710 * Helper method for double taps. 711 */ 712 MOZ_CAN_RUN_SCRIPT_BOUNDARY 713 nsEventStatus OnDoubleTap(const TapGestureInput& aEvent); 714 715 /** 716 * Helper method for double taps where the double-tap gesture is disabled. 717 */ 718 nsEventStatus OnSecondTap(const TapGestureInput& aEvent); 719 720 /** 721 * Helper method to cancel any gesture currently going to Gecko. Used 722 * primarily when a user taps the screen over some clickable content but then 723 * pans down instead of letting go (i.e. to cancel a previous touch so that a 724 * new one can properly take effect. 725 */ 726 nsEventStatus OnCancelTap(const TapGestureInput& aEvent); 727 728 /** 729 * The following five methods modify the scroll offset. For the APZC 730 * representing the RCD-RSF, they also recalculate the offset of the layout 731 * viewport. 732 */ 733 734 /** 735 * Scroll the scroll frame to an X,Y offset. 736 */ 737 void SetVisualScrollOffset(const CSSPoint& aOffset); 738 739 /** 740 * Scroll the scroll frame to an X,Y offset, clamping the resulting scroll 741 * offset to the scroll range. 742 */ 743 void ClampAndSetVisualScrollOffset(const CSSPoint& aOffset); 744 745 /** 746 * Scroll the scroll frame by an X,Y offset. 747 * The resulting scroll offset is not clamped to the scrollable rect; 748 * the caller must ensure it stays within range. 749 */ 750 void ScrollBy(const CSSPoint& aOffset); 751 752 /** 753 * Scroll the scroll frame by an X,Y offset, clamping the resulting 754 * scroll offset to the scroll range. 755 */ 756 void ScrollByAndClamp(const CSSPoint& aOffset); 757 758 /** 759 * Scales the viewport by an amount (note that it multiplies this scale in to 760 * the current scale, it doesn't set it to |aScale|). Also considers a focus 761 * point so that the page zooms inward/outward from that point. 762 */ 763 void ScaleWithFocus(float aScale, const CSSPoint& aFocus); 764 765 /** 766 * Schedules a composite on the compositor thread. 767 */ 768 void ScheduleComposite(); 769 770 /** 771 * Schedules a composite, and if enough time has elapsed since the last 772 * paint, a paint. 773 */ 774 void ScheduleCompositeAndMaybeRepaint(); 775 776 /** 777 * Gets the start point of the current touch. 778 * This only makes sense if a touch is currently happening and OnTouchMove() 779 * or the equivalent for pan gestures is being invoked. 780 */ 781 ParentLayerPoint PanStart() const; 782 783 /** 784 * Gets a vector of the velocities of each axis. 785 */ 786 const ParentLayerPoint GetVelocityVector() const; 787 788 /** 789 * Sets the velocities of each axis. 790 */ 791 void SetVelocityVector(const ParentLayerPoint& aVelocityVector); 792 793 /** 794 * Gets the first touch point from a MultiTouchInput. This gets only 795 * the first one and assumes the rest are either missing or not relevant. 796 */ 797 ParentLayerPoint GetFirstTouchPoint(const MultiTouchInput& aEvent); 798 799 /** 800 * Gets the relevant point in the event 801 * (eg. first touch, or pinch focus point) of the given InputData. 802 */ 803 ExternalPoint GetExternalPoint(const InputData& aEvent); 804 805 /** 806 * Gets the relevant point in the event, in external screen coordinates. 807 */ 808 ExternalPoint GetFirstExternalTouchPoint(const MultiTouchInput& aEvent); 809 810 /** 811 * Gets the amount by which this APZC is overscrolled along both axes. 812 */ 813 ParentLayerPoint GetOverscrollAmount() const; 814 815 private: 816 // Internal version of GetOverscrollAmount() which does not set 817 // the test async properties. 818 ParentLayerPoint GetOverscrollAmountInternal() const; 819 820 protected: 821 /** 822 * Returns SideBits where this APZC is overscrolled. 823 */ 824 SideBits GetOverscrollSideBits() const; 825 826 /** 827 * Restore the amount by which this APZC is overscrolled along both axes 828 * to the specified amount. This is for test-related use; overscrolling 829 * as a result of user input should happen via OverscrollBy(). 830 */ 831 void RestoreOverscrollAmount(const ParentLayerPoint& aOverscroll); 832 833 /** 834 * Sets the panning state basing on the pan direction angle and current 835 * touch-action value. 836 */ 837 void HandlePanningWithTouchAction(double angle); 838 839 /** 840 * Sets the panning state ignoring the touch action value. 841 */ 842 void HandlePanning(double angle); 843 844 /** 845 * Update the panning state and axis locks. 846 */ 847 void HandlePanningUpdate(const ScreenPoint& aDelta); 848 849 /** 850 * Set and update the pinch lock 851 */ 852 void HandlePinchLocking(const PinchGestureInput& aEvent); 853 854 /** 855 * Sets up anything needed for panning. This takes us out of the "TOUCHING" 856 * state and starts actually panning us. We provide the physical pixel 857 * position of the start point so that the pan gesture is calculated 858 * regardless of if the window/GeckoView moved during the pan. 859 */ 860 nsEventStatus StartPanning(const ExternalPoint& aStartPoint, 861 const TimeStamp& aEventTime); 862 863 /** 864 * Wrapper for Axis::UpdateWithTouchAtDevicePoint(). Calls this function for 865 * both axes and factors in the time delta from the last update. 866 */ 867 void UpdateWithTouchAtDevicePoint(const MultiTouchInput& aEvent); 868 869 /** 870 * Does any panning required due to a new touch event. 871 */ 872 void TrackTouch(const MultiTouchInput& aEvent); 873 874 /** 875 * Register the start of a touch or pan gesture at the given position and 876 * time. 877 */ 878 void StartTouch(const ParentLayerPoint& aPoint, TimeStamp aTimestamp); 879 880 /** 881 * Register the end of a touch or pan gesture at the given time. 882 */ 883 void EndTouch(TimeStamp aTimestamp); 884 885 /** 886 * Utility function to send updated FrameMetrics to Gecko so that it can paint 887 * the displayport area. Calls into GeckoContentController to do the actual 888 * work. This call will use the current metrics. If this function is called 889 * from a non-main thread, it will redispatch itself to the main thread, and 890 * use the latest metrics during the redispatch. 891 */ 892 void RequestContentRepaint( 893 RepaintUpdateType aUpdateType = RepaintUpdateType::eUserAction); 894 895 /** 896 * Send the provided metrics to Gecko to trigger a repaint. This function 897 * may filter duplicate calls with the same metrics. This function must be 898 * called on the main thread. 899 */ 900 void RequestContentRepaint(const FrameMetrics& aFrameMetrics, 901 const ParentLayerPoint& aVelocity, 902 const ScreenMargin& aDisplayportMargins, 903 RepaintUpdateType aUpdateType); 904 905 /** 906 * Gets the current frame metrics. This is *not* the Gecko copy stored in the 907 * layers code. 908 */ 909 const FrameMetrics& GetFrameMetrics() const; 910 911 /** 912 * Gets the current scroll metadata. This is *not* the Gecko copy stored in 913 * the layers code/ 914 */ 915 const ScrollMetadata& GetScrollMetadata() const; 916 917 /** 918 * Gets the pointer to the apzc tree manager. All the access to tree manager 919 * should be made via this method and not via private variable since this 920 * method ensures that no lock is set. 921 */ 922 APZCTreeManager* GetApzcTreeManager() const; 923 924 void AssertOnSamplerThread() const; 925 void AssertOnUpdaterThread() const; 926 927 /** 928 * Convert ScreenPoint relative to the screen to LayoutDevicePoint relative 929 * to the parent document. This excludes the transient compositor transform. 930 * NOTE: This must be converted to LayoutDevicePoint relative to the child 931 * document before sending over IPC to a child process. 932 */ 933 Maybe<LayoutDevicePoint> ConvertToGecko(const ScreenIntPoint& aPoint); 934 935 enum AxisLockMode { 936 FREE, /* No locking at all */ 937 STANDARD, /* Default axis locking mode that remains locked until pan ends*/ 938 STICKY, /* Allow lock to be broken, with hysteresis */ 939 }; 940 941 static AxisLockMode GetAxisLockMode(); 942 943 enum PinchLockMode { 944 PINCH_FREE, /* No locking at all */ 945 PINCH_STANDARD, /* Default pinch locking mode that remains locked until 946 pinch gesture ends*/ 947 PINCH_STICKY, /* Allow lock to be broken, with hysteresis */ 948 }; 949 950 static PinchLockMode GetPinchLockMode(); 951 952 // Helper function for OnSingleTapUp(), OnSingleTapConfirmed(), and 953 // OnLongPressUp(). 954 nsEventStatus GenerateSingleTap(GeckoContentController::TapType aType, 955 const ScreenIntPoint& aPoint, 956 mozilla::Modifiers aModifiers); 957 958 // Common processing at the end of a touch block. 959 void OnTouchEndOrCancel(); 960 961 LayersId mLayersId; 962 RefPtr<CompositorController> mCompositorController; 963 RefPtr<MetricsSharingController> mMetricsSharingController; 964 965 /* Access to the following two fields is protected by the mRefPtrMonitor, 966 since they are accessed on the UI thread but can be cleared on the 967 updater thread. */ 968 RefPtr<GeckoContentController> mGeckoContentController; 969 RefPtr<GestureEventListener> mGestureEventListener; 970 mutable Monitor mRefPtrMonitor; 971 972 // This is a raw pointer to avoid introducing a reference cycle between 973 // AsyncPanZoomController and APZCTreeManager. Since these objects don't 974 // live on the main thread, we can't use the cycle collector with them. 975 // The APZCTreeManager owns the lifetime of the APZCs, so nulling this 976 // pointer out in Destroy() will prevent accessing deleted memory. 977 Atomic<APZCTreeManager*> mTreeManager; 978 979 /* Utility functions that return a addrefed pointer to the corresponding 980 * fields. */ 981 already_AddRefed<GeckoContentController> GetGeckoContentController() const; 982 already_AddRefed<GestureEventListener> GetGestureEventListener() const; 983 984 PlatformSpecificStateBase* GetPlatformSpecificState(); 985 986 /** 987 * Convenience functions to get the corresponding fields of mZoomContraints 988 * while holding mRecursiveMutex. 989 */ 990 bool ZoomConstraintsAllowZoom() const; 991 bool ZoomConstraintsAllowDoubleTapZoom() const; 992 993 protected: 994 // Both |mScrollMetadata| and |mLastContentPaintMetrics| are protected by the 995 // monitor. Do not read from or modify them without locking. 996 ScrollMetadata mScrollMetadata; 997 998 // Protects |mScrollMetadata|, |mLastContentPaintMetrics| and |mState|. 999 // Before manipulating |mScrollMetadata| or |mLastContentPaintMetrics| the 1000 // monitor should be held. When setting |mState|, either the SetState() 1001 // function can be used, or the monitor can be held and then |mState| updated. 1002 // IMPORTANT: See the note about lock ordering at the top of 1003 // APZCTreeManager.h. This is mutable to allow entering it from 'const' 1004 // methods; doing otherwise would significantly limit what methods could be 1005 // 'const'. 1006 // FIXME: Please keep in mind that due to some existing coupled relationships 1007 // among the class members, we should be aware of indirect usage of the 1008 // monitor-protected members. That is, although this monitor isn't required to 1009 // be held before manipulating non-protected class members, some functions on 1010 // those members might indirectly manipulate the protected members; in such 1011 // cases, the monitor should still be held. Let's take mX.CanScroll for 1012 // example: 1013 // Axis::CanScroll(ParentLayerCoord) calls Axis::CanScroll() which calls 1014 // Axis::GetPageLength() which calls Axis::GetFrameMetrics() which calls 1015 // AsyncPanZoomController::GetFrameMetrics(), therefore, this monitor should 1016 // be held before calling the CanScroll function of |mX| and |mY|. These 1017 // coupled relationships bring us the burden of taking care of when the 1018 // monitor should be held, so they should be decoupled in the future. 1019 mutable RecursiveMutex mRecursiveMutex; 1020 1021 private: 1022 // Metadata of the container layer corresponding to this APZC. This is 1023 // stored here so that it is accessible from the UI/controller thread. 1024 // These are the metrics at last content paint, the most recent 1025 // values we were notified of in NotifyLayersUpdate(). Since it represents 1026 // the Gecko state, it should be used as a basis for untransformation when 1027 // sending messages back to Gecko. 1028 ScrollMetadata mLastContentPaintMetadata; 1029 FrameMetrics& mLastContentPaintMetrics; // for convenience, refers to 1030 // mLastContentPaintMetadata.mMetrics 1031 // The last content repaint request. 1032 RepaintRequest mLastPaintRequestMetrics; 1033 // The metrics that we expect content to have. This is updated when we 1034 // request a content repaint, and when we receive a shadow layers update. 1035 // This allows us to transform events into Gecko's coordinate space. 1036 ExpectedGeckoMetrics mExpectedGeckoMetrics; 1037 1038 // This holds important state from the Metrics() at previous times 1039 // SampleCompositedAsyncTransform() was called. This will always have at least 1040 // one item. mRecursiveMutex must be held when using or modifying this member. 1041 // Samples should be inserted to the "back" of the deque and extracted from 1042 // the "front". 1043 std::deque<SampledAPZCState> mSampledState; 1044 1045 // Groups state variables that are specific to a platform. 1046 // Initialized on first use. 1047 UniquePtr<PlatformSpecificStateBase> mPlatformSpecificState; 1048 1049 AxisX mX; 1050 AxisY mY; 1051 1052 // This flag is set to true when we are in a axis-locked pan as a result of 1053 // the touch-action CSS property. 1054 bool mPanDirRestricted; 1055 1056 // This flag is set to true when we are in a pinch-locked state. ie: user 1057 // is performing a two-finger pan rather than a pinch gesture 1058 bool mPinchLocked; 1059 1060 // Stores the pinch events that occured within a given timeframe. Used to 1061 // calculate the focusChange and spanDistance within a fixed timeframe. 1062 // RecentEventsBuffer is not threadsafe. Should only be accessed on the 1063 // controller thread. 1064 RecentEventsBuffer<PinchGestureInput> mPinchEventBuffer; 1065 1066 // Most up-to-date constraints on zooming. These should always be reasonable 1067 // values; for example, allowing a min zoom of 0.0 can cause very bad things 1068 // to happen. Hold mRecursiveMutex when accessing this. 1069 ZoomConstraints mZoomConstraints; 1070 1071 // The last time the compositor has sampled the content transform for this 1072 // frame. 1073 SampleTime mLastSampleTime; 1074 1075 // The last sample time at which we submitted a checkerboarding report. 1076 SampleTime mLastCheckerboardReport; 1077 1078 // Stores the previous focus point if there is a pinch gesture happening. Used 1079 // to allow panning by moving multiple fingers (thus moving the focus point). 1080 ParentLayerPoint mLastZoomFocus; 1081 1082 RefPtr<AsyncPanZoomAnimation> mAnimation; 1083 1084 UniquePtr<OverscrollEffectBase> mOverscrollEffect; 1085 1086 // Zoom animation id, used for zooming in WebRender. This should only be 1087 // set on the APZC instance for the root content document (i.e. the one we 1088 // support zooming on), and is only used if WebRender is enabled. The 1089 // animation id itself refers to the transform animation id that was set on 1090 // the stacking context in the WR display list. By changing the transform 1091 // associated with this id, we can adjust the scaling that WebRender applies, 1092 // thereby controlling the zoom. 1093 Maybe<uint64_t> mZoomAnimationId; 1094 1095 // Position on screen where user first put their finger down. 1096 ExternalPoint mStartTouch; 1097 1098 // Accessing mScrollPayload needs to be protected by mRecursiveMutex 1099 Maybe<CompositionPayload> mScrollPayload; 1100 1101 friend class Axis; 1102 1103 public: 1104 Maybe<CompositionPayload> NotifyScrollSampling(); 1105 1106 /** 1107 * Invoke |callable|, passing |mLastContentPaintMetrics| as argument, 1108 * while holding the APZC lock required to access |mLastContentPaintMetrics|. 1109 * This allows code outside of an AsyncPanZoomController method implementation 1110 * to access |mLastContentPaintMetrics| without having to make a copy of it. 1111 * Passes through the return value of |callable|. 1112 */ 1113 template <typename Callable> 1114 auto CallWithLastContentPaintMetrics(const Callable& callable) const 1115 -> decltype(callable(mLastContentPaintMetrics)) { 1116 RecursiveMutexAutoLock lock(mRecursiveMutex); 1117 return callable(mLastContentPaintMetrics); 1118 } 1119 1120 void SetZoomAnimationId(const Maybe<uint64_t>& aZoomAnimationId); 1121 Maybe<uint64_t> GetZoomAnimationId() const; 1122 1123 /* =================================================================== 1124 * The functions and members in this section are used to expose 1125 * the current async transform state to callers. 1126 */ 1127 public: 1128 /** 1129 * Allows consumers of async transforms to specify for what purpose they are 1130 * using the async transform: 1131 * 1132 * |eForHitTesting| is intended for hit-testing and other uses that need 1133 * the most up-to-date transform, reflecting all events 1134 * that have been processed so far, even if the transform 1135 * is not yet reflected visually. 1136 * |eForCompositing| is intended for the transform that should be reflected 1137 * visually. 1138 * 1139 * For example, if an APZC has metrics with the mForceDisableApz flag set, 1140 * then the |eForCompositing| async transform will be empty, while the 1141 * |eForHitTesting| async transform will reflect processed input events 1142 * regardless of mForceDisableApz. 1143 */ 1144 enum AsyncTransformConsumer { 1145 eForHitTesting, 1146 eForCompositing, 1147 }; 1148 1149 /** 1150 * Get the current layout viewport of the scrollable frame corresponding to 1151 * this APZC. 1152 */ 1153 CSSRect GetCurrentAsyncLayoutViewport(AsyncTransformConsumer aMode) const; 1154 1155 /** 1156 * Get the current scroll offset of the scrollable frame corresponding 1157 * to this APZC, including the effects of any asynchronous panning and 1158 * zooming, in ParentLayer pixels. 1159 */ 1160 ParentLayerPoint GetCurrentAsyncScrollOffset( 1161 AsyncTransformConsumer aMode) const; 1162 1163 /** 1164 * Get the current scroll offset of the scrollable frame corresponding 1165 * to this APZC, including the effects of any asynchronous panning, in 1166 * CSS pixels. 1167 */ 1168 CSSPoint GetCurrentAsyncScrollOffsetInCssPixels( 1169 AsyncTransformConsumer aMode) const; 1170 1171 /** 1172 * Return a visual effect that reflects this apzc's 1173 * overscrolled state, if any. 1174 */ 1175 AsyncTransformComponentMatrix GetOverscrollTransform( 1176 AsyncTransformConsumer aMode) const; 1177 1178 /** 1179 * Returns the incremental transformation corresponding to the async pan/zoom 1180 * in progress. That is, when this transform is multiplied with the layer's 1181 * existing transform, it will make the layer appear with the desired pan/zoom 1182 * amount. 1183 * The transform can have both scroll and zoom components; the caller can 1184 * request just one or the other, or both, via the |aComponents| parameter. 1185 * When only the eLayout component is requested, the returned translation 1186 * should really be a LayerPoint, rather than a ParentLayerPoint, as it will 1187 * not be scaled by the asynchronous zoom. 1188 */ 1189 AsyncTransform GetCurrentAsyncTransform( 1190 AsyncTransformConsumer aMode, 1191 AsyncTransformComponents aComponents = LayoutAndVisual) const; 1192 1193 /** 1194 * Returns the same transform as GetCurrentAsyncTransform(), but includes 1195 * any transform due to axis over-scroll. 1196 */ 1197 AsyncTransformComponentMatrix GetCurrentAsyncTransformWithOverscroll( 1198 AsyncTransformConsumer aMode, 1199 AsyncTransformComponents aComponents = LayoutAndVisual) const; 1200 1201 /** 1202 * Returns the "zoom" bits of the transform. This includes both the rasterized 1203 * (layout device to layer scale) and async (layer scale to parent layer 1204 * scale) components of the zoom. 1205 */ 1206 LayoutDeviceToParentLayerScale GetCurrentPinchZoomScale( 1207 AsyncTransformConsumer aMode) const; 1208 GetCompositionBounds()1209 ParentLayerRect GetCompositionBounds() const { 1210 RecursiveMutexAutoLock lock(mRecursiveMutex); 1211 return mScrollMetadata.GetMetrics().GetCompositionBounds(); 1212 } 1213 GetCumulativeResolution()1214 LayoutDeviceToLayerScale2D GetCumulativeResolution() const { 1215 RecursiveMutexAutoLock lock(mRecursiveMutex); 1216 return mScrollMetadata.GetMetrics().GetCumulativeResolution(); 1217 } 1218 1219 // Returns the delta for the given InputData. 1220 ParentLayerPoint GetDeltaForEvent(const InputData& aEvent) const; 1221 1222 private: 1223 /** 1224 * Advances to the next sample, if there is one, the list of sampled states 1225 * stored in mSampledState. This will make the result of 1226 * |GetCurrentAsyncTransform(eForCompositing)| and similar functions reflect 1227 * the async scroll offset and zoom of the next sample. See also 1228 * SampleCompositedAsyncTransform which creates the samples. 1229 */ 1230 void AdvanceToNextSample(); 1231 1232 /** 1233 * Samples the composited async transform, storing the result into 1234 * mSampledState. This will make the result of 1235 * |GetCurrentAsyncTransform(eForCompositing)| and similar functions reflect 1236 * the async scroll offset and zoom stored in |Metrics()| when the sample 1237 * is activated via some future call to |AdvanceToNextSample|. 1238 * 1239 * Returns true if the newly sampled value is different from the last 1240 * sampled value. 1241 */ 1242 bool SampleCompositedAsyncTransform( 1243 const RecursiveMutexAutoLock& aProofOfLock); 1244 1245 /** 1246 * Updates the sample at the front of mSampledState with the latest 1247 * metrics. This makes the result of 1248 * |GetCurrentAsyncTransform(eForCompositing)| reflect the current Metrics(). 1249 */ 1250 void ResampleCompositedAsyncTransform( 1251 const RecursiveMutexAutoLock& aProofOfLock); 1252 1253 /* 1254 * Helper functions to query the async layout viewport, scroll offset, and 1255 * zoom either directly from |Metrics()|, or from cached variables that 1256 * store the required value from the last time it was sampled by calling 1257 * SampleCompositedAsyncTransform(), depending on who is asking. 1258 */ 1259 CSSRect GetEffectiveLayoutViewport( 1260 AsyncTransformConsumer aMode, 1261 const RecursiveMutexAutoLock& aProofOfLock) const; 1262 CSSPoint GetEffectiveScrollOffset( 1263 AsyncTransformConsumer aMode, 1264 const RecursiveMutexAutoLock& aProofOfLock) const; 1265 CSSToParentLayerScale2D GetEffectiveZoom( 1266 AsyncTransformConsumer aMode, 1267 const RecursiveMutexAutoLock& aProofOfLock) const; 1268 1269 /** 1270 * Returns the visible portion of the content scrolled by this APZC, in 1271 * CSS pixels. The caller must have acquired the mRecursiveMutex lock. 1272 */ 1273 CSSRect GetVisibleRect(const RecursiveMutexAutoLock& aProofOfLock) const; 1274 1275 /** 1276 * Returns a pair of displacements both in logical/physical units for 1277 * |aEvent|. 1278 */ 1279 std::tuple<ParentLayerPoint, ScreenPoint> GetDisplacementsForPanGesture( 1280 const PanGestureInput& aEvent); 1281 1282 private: 1283 friend class AutoApplyAsyncTestAttributes; 1284 1285 bool SuppressAsyncScrollOffset() const; 1286 1287 /** 1288 * Applies |mTestAsyncScrollOffset| and |mTestAsyncZoom| to this 1289 * AsyncPanZoomController. Calls |SampleCompositedAsyncTransform| to ensure 1290 * that the GetCurrentAsync* functions consider the test offset and zoom in 1291 * their computations. 1292 */ 1293 void ApplyAsyncTestAttributes(const RecursiveMutexAutoLock& aProofOfLock); 1294 1295 /** 1296 * Sets this AsyncPanZoomController's FrameMetrics to |aPrevFrameMetrics| and 1297 * calls |SampleCompositedAsyncTransform| to unapply any test values applied 1298 * by |ApplyAsyncTestAttributes|. 1299 */ 1300 void UnapplyAsyncTestAttributes(const RecursiveMutexAutoLock& aProofOfLock, 1301 const FrameMetrics& aPrevFrameMetrics, 1302 const ParentLayerPoint& aPrevOverscroll); 1303 1304 /* =================================================================== 1305 * The functions and members in this section are used to manage 1306 * the state that tracks what this APZC is doing with the input events. 1307 */ 1308 protected: 1309 enum PanZoomState { 1310 NOTHING, /* no touch-start events received */ 1311 FLING, /* all touches removed, but we're still scrolling page */ 1312 TOUCHING, /* one touch-start event received */ 1313 1314 PANNING, /* panning the frame */ 1315 PANNING_LOCKED_X, /* touch-start followed by move (i.e. panning with axis 1316 lock) X axis */ 1317 PANNING_LOCKED_Y, /* as above for Y axis */ 1318 1319 PAN_MOMENTUM, /* like PANNING, but controlled by momentum PanGestureInput 1320 events */ 1321 1322 PINCHING, /* nth touch-start, where n > 1. this mode allows pan and zoom */ 1323 ANIMATING_ZOOM, /* animated zoom to a new rect */ 1324 OVERSCROLL_ANIMATION, /* Spring-based animation used to relieve overscroll 1325 once the finger is lifted. */ 1326 SMOOTH_SCROLL, /* Smooth scrolling to destination, with physics 1327 controlled by prefs specific to the scroll origin. */ 1328 SMOOTHMSD_SCROLL, /* SmoothMSD scrolling to destination. Used by 1329 CSSOM-View smooth scroll-behavior */ 1330 WHEEL_SCROLL, /* Smooth scrolling to a destination for a wheel event. */ 1331 KEYBOARD_SCROLL, /* Smooth scrolling to a destination for a keyboard event. 1332 */ 1333 AUTOSCROLL, /* Autoscroll animation. */ 1334 SCROLLBAR_DRAG /* Async scrollbar drag. */ 1335 }; 1336 // This is in theory protected by |mRecursiveMutex|; that is, it should be 1337 // held whenever this is updated. In practice though... see bug 897017. 1338 PanZoomState mState; 1339 1340 static bool IsPanningState(PanZoomState aState); 1341 1342 /** 1343 * Returns whether the specified PanZoomState does not need to be reset when 1344 * a scroll offset update is processed. 1345 */ 1346 static bool CanHandleScrollOffsetUpdate(PanZoomState aState); 1347 1348 /** 1349 * Determine whether a main-thread scroll offset update should result in 1350 * a call to CancelAnimation() (which interrupts in-progress animations and 1351 * gestures). 1352 * 1353 * If the update is a relative update, |aRelativeDelta| contains its amount. 1354 * If the update is not a relative update, GetMetrics() should already reflect 1355 * the new offset at the time of the call. 1356 */ 1357 bool ShouldCancelAnimationForScrollUpdate( 1358 const Maybe<CSSPoint>& aRelativeDelta); 1359 1360 private: 1361 friend class StateChangeNotificationBlocker; 1362 /** 1363 * A counter of how many StateChangeNotificationBlockers are active. 1364 * A non-zero count will prevent state change notifications from 1365 * being dispatched. Only code that holds mRecursiveMutex should touch this. 1366 */ 1367 int mNotificationBlockers; 1368 1369 /** 1370 * Helper to set the current state. Holds the monitor before actually setting 1371 * it and fires content controller events based on state changes. Always set 1372 * the state using this call, do not set it directly. 1373 */ 1374 void SetState(PanZoomState aState); 1375 /** 1376 * Fire content controller notifications about state changes, assuming no 1377 * StateChangeNotificationBlocker has been activated. 1378 */ 1379 void DispatchStateChangeNotification(PanZoomState aOldState, 1380 PanZoomState aNewState); 1381 /** 1382 * Internal helpers for checking general state of this apzc. 1383 */ 1384 bool IsInTransformingState() const; 1385 static bool IsTransformingState(PanZoomState aState); 1386 1387 /* =================================================================== 1388 * The functions and members in this section are used to manage 1389 * blocks of touch events and the state needed to deal with content 1390 * listeners. 1391 */ 1392 public: 1393 /** 1394 * Flush a repaint request if one is needed, without throttling it with the 1395 * paint throttler. 1396 */ 1397 void FlushRepaintForNewInputBlock(); 1398 1399 /** 1400 * Given an input event and the touch block it belongs to, check if the 1401 * event can lead to a panning/zooming behavior. 1402 * This is primarily used to figure out when to dispatch the pointercancel 1403 * event for the pointer events spec. 1404 */ 1405 bool ArePointerEventsConsumable(TouchBlockState* aBlock, 1406 const MultiTouchInput& aInput); 1407 1408 /** 1409 * Clear internal state relating to touch input handling. 1410 */ 1411 void ResetTouchInputState(); 1412 1413 /** 1414 Clear internal state relating to pan gesture input handling. 1415 */ 1416 void ResetPanGestureInputState(); 1417 1418 /** 1419 * Gets a ref to the input queue that is shared across the entire tree 1420 * manager. 1421 */ 1422 const RefPtr<InputQueue>& GetInputQueue() const; 1423 1424 private: 1425 void CancelAnimationAndGestureState(); 1426 1427 RefPtr<InputQueue> mInputQueue; 1428 InputBlockState* GetCurrentInputBlock() const; 1429 TouchBlockState* GetCurrentTouchBlock() const; 1430 bool HasReadyTouchBlock() const; 1431 1432 PanGestureBlockState* GetCurrentPanGestureBlock() const; 1433 PinchGestureBlockState* GetCurrentPinchGestureBlock() const; 1434 1435 private: 1436 /* =================================================================== 1437 * The functions and members in this section are used to manage 1438 * fling animations, smooth scroll animations, and overscroll 1439 * during a fling or smooth scroll. 1440 */ 1441 public: 1442 /** 1443 * Attempt a fling with the velocity specified in |aHandoffState|. 1444 * |aHandoffState.mIsHandoff| should be true iff. the fling was handed off 1445 * from a previous APZC, and determines whether acceleration is applied 1446 * to the fling. 1447 * We only accept the fling in the direction(s) in which we are pannable. 1448 * Returns the "residual velocity", i.e. the portion of 1449 * |aHandoffState.mVelocity| that this APZC did not consume. 1450 */ 1451 ParentLayerPoint AttemptFling(const FlingHandoffState& aHandoffState); 1452 1453 ParentLayerPoint AdjustHandoffVelocityForOverscrollBehavior( 1454 ParentLayerPoint& aHandoffVelocity) const; 1455 1456 private: 1457 friend class StackScrollerFlingAnimation; 1458 friend class AutoscrollAnimation; 1459 template <typename FlingPhysics> 1460 friend class GenericFlingAnimation; 1461 friend class AndroidFlingPhysics; 1462 friend class DesktopFlingPhysics; 1463 friend class OverscrollAnimation; 1464 friend class SmoothMsdScrollAnimation; 1465 friend class GenericScrollAnimation; 1466 friend class WheelScrollAnimation; 1467 friend class KeyboardScrollAnimation; 1468 friend class ZoomAnimation; 1469 1470 friend class GenericOverscrollEffect; 1471 friend class WidgetOverscrollEffect; 1472 friend struct apz::AsyncScrollThumbTransformer; 1473 1474 FlingAccelerator mFlingAccelerator; 1475 1476 // Indicates if the repaint-during-pinch timer is currently set 1477 bool mPinchPaintTimerSet; 1478 1479 // Deal with overscroll resulting from a fling animation. This is only ever 1480 // called on APZC instances that were actually performing a fling. 1481 // The overscroll is handled by trying to hand the fling off to an APZC 1482 // later in the handoff chain, or if there are no takers, continuing the 1483 // fling and entering an overscrolled state. 1484 void HandleFlingOverscroll( 1485 const ParentLayerPoint& aVelocity, SideBits aOverscrollSideBits, 1486 const RefPtr<const OverscrollHandoffChain>& aOverscrollHandoffChain, 1487 const RefPtr<const AsyncPanZoomController>& aScrolledApzc); 1488 1489 void HandleSmoothScrollOverscroll(const ParentLayerPoint& aVelocity, 1490 SideBits aOverscrollSideBits); 1491 1492 // Start an overscroll animation with the given initial velocity. 1493 void StartOverscrollAnimation(const ParentLayerPoint& aVelocity, 1494 SideBits aOverscrollSideBits); 1495 1496 // Start a smooth-scrolling animation to the given destination, with physics 1497 // based on the prefs for the indicated origin. 1498 void SmoothScrollTo(const CSSPoint& aDestination, 1499 const ScrollOrigin& aOrigin); 1500 1501 // Start a smooth-scrolling animation to the given destination, with MSD 1502 // physics that is suited for scroll-snapping. 1503 void SmoothMsdScrollTo(const CSSPoint& aDestination); 1504 1505 // Returns whether overscroll is allowed during an event. 1506 bool AllowScrollHandoffInCurrentBlock() const; 1507 1508 // Invoked by the pinch repaint timer. 1509 void DoDelayedRequestContentRepaint(); 1510 1511 // Compute the number of ParentLayer pixels per (Screen) inch at the given 1512 // point and in the given direction. 1513 float ComputePLPPI(ParentLayerPoint aPoint, 1514 ParentLayerPoint aDirection) const; 1515 1516 Maybe<CSSPoint> GetCurrentAnimationDestination( 1517 const RecursiveMutexAutoLock& aProofOfLock) const; 1518 1519 /* =================================================================== 1520 * The functions and members in this section are used to make ancestor chains 1521 * out of APZC instances. These chains can only be walked or manipulated 1522 * while holding the lock in the associated APZCTreeManager instance. 1523 */ 1524 public: SetParent(AsyncPanZoomController * aParent)1525 void SetParent(AsyncPanZoomController* aParent) { mParent = aParent; } 1526 GetParent()1527 AsyncPanZoomController* GetParent() const { return mParent; } 1528 1529 /* Returns true if there is no APZC higher in the tree with the same 1530 * layers id. 1531 */ HasNoParentWithSameLayersId()1532 bool HasNoParentWithSameLayersId() const { 1533 return !mParent || (mParent->mLayersId != mLayersId); 1534 } 1535 IsRootForLayersId()1536 bool IsRootForLayersId() const { 1537 RecursiveMutexAutoLock lock(mRecursiveMutex); 1538 return mScrollMetadata.IsLayersIdRoot(); 1539 } 1540 IsRootContent()1541 bool IsRootContent() const { 1542 RecursiveMutexAutoLock lock(mRecursiveMutex); 1543 return Metrics().IsRootContent(); 1544 } 1545 1546 private: 1547 // |mTreeManager| belongs in this section but it's declaration is a bit 1548 // further above due to initialization-order constraints. 1549 1550 RefPtr<AsyncPanZoomController> mParent; 1551 1552 /* =================================================================== 1553 * The functions and members in this section are used for scrolling, 1554 * including handing off scroll to another APZC, and overscrolling. 1555 */ 1556 GetScrollId()1557 ScrollableLayerGuid::ViewID GetScrollId() const { 1558 RecursiveMutexAutoLock lock(mRecursiveMutex); 1559 return Metrics().GetScrollId(); 1560 } 1561 1562 public: GetScrollHandoffParentId()1563 ScrollableLayerGuid::ViewID GetScrollHandoffParentId() const { 1564 return mScrollMetadata.GetScrollParentId(); 1565 } 1566 1567 /** 1568 * Attempt to scroll in response to a touch-move from |aStartPoint| to 1569 * |aEndPoint|, which are in our (transformed) screen coordinates. 1570 * Due to overscroll handling, there may not actually have been a touch-move 1571 * at these points, but this function will scroll as if there had been. 1572 * If this attempt causes overscroll (i.e. the layer cannot be scrolled 1573 * by the entire amount requested), the overscroll is passed back to the 1574 * tree manager via APZCTreeManager::DispatchScroll(). If the tree manager 1575 * does not find an APZC further in the handoff chain to accept the 1576 * overscroll, and this APZC is pannable, this APZC enters an overscrolled 1577 * state. 1578 * |aOverscrollHandoffChain| and |aOverscrollHandoffChainIndex| are used by 1579 * the tree manager to keep track of which APZC to hand off the overscroll 1580 * to; this function increments the chain and the index and passes it on to 1581 * APZCTreeManager::DispatchScroll() in the event of overscroll. 1582 * Returns true iff. this APZC, or an APZC further down the 1583 * handoff chain, accepted the scroll (possibly entering an overscrolled 1584 * state). If this returns false, the caller APZC knows that it should enter 1585 * an overscrolled state itself if it can. 1586 * aStartPoint and aEndPoint are modified depending on how much of the 1587 * scroll gesture was consumed by APZCs in the handoff chain. 1588 */ 1589 bool AttemptScroll(ParentLayerPoint& aStartPoint, ParentLayerPoint& aEndPoint, 1590 OverscrollHandoffState& aOverscrollHandoffState); 1591 1592 void FlushRepaintForOverscrollHandoff(); 1593 1594 /** 1595 * If overscrolled, start a snap-back animation and return true. Even if not 1596 * overscrolled, this function tries to snap back to if there's an applicable 1597 * scroll snap point. 1598 * Otherwise return false. 1599 */ 1600 bool SnapBackIfOverscrolled(); 1601 1602 /** 1603 * NOTE: Similar to above but this function doesn't snap back to the scroll 1604 * snap point. 1605 */ 1606 bool SnapBackIfOverscrolledForMomentum(const ParentLayerPoint& aVelocity); 1607 1608 /** 1609 * Build the chain of APZCs along which scroll will be handed off when 1610 * this APZC receives input events. 1611 * 1612 * Notes on lifetime and const-correctness: 1613 * - The returned handoff chain is |const|, to indicate that it cannot be 1614 * changed after being built. 1615 * - When passing the chain to a function that uses it without storing it, 1616 * pass it by reference-to-const (as in |const OverscrollHandoffChain&|). 1617 * - When storing the chain, store it by RefPtr-to-const (as in 1618 * |RefPtr<const OverscrollHandoffChain>|). This ensures the chain is 1619 * kept alive. Note that queueing a task that uses the chain as an 1620 * argument constitutes storing, as the task may outlive its queuer. 1621 * - When passing the chain to a function that will store it, pass it as 1622 * |const RefPtr<const OverscrollHandoffChain>&|. This allows the 1623 * function to copy it into the |RefPtr<const OverscrollHandoffChain>| 1624 * that will store it, while avoiding an unnecessary copy (and thus 1625 * AddRef() and Release()) when passing it. 1626 */ 1627 RefPtr<const OverscrollHandoffChain> BuildOverscrollHandoffChain(); 1628 1629 private: 1630 /** 1631 * A helper function for calling APZCTreeManager::DispatchScroll(). 1632 * Guards against the case where the APZC is being concurrently destroyed 1633 * (and thus mTreeManager is being nulled out). 1634 */ 1635 bool CallDispatchScroll(ParentLayerPoint& aStartPoint, 1636 ParentLayerPoint& aEndPoint, 1637 OverscrollHandoffState& aOverscrollHandoffState); 1638 1639 void RecordScrollPayload(const TimeStamp& aTimeStamp); 1640 1641 /** 1642 * A helper function for overscrolling during panning. This is a wrapper 1643 * around OverscrollBy() that also implements restrictions on entering 1644 * overscroll based on the pan angle. 1645 */ 1646 void OverscrollForPanning(ParentLayerPoint& aOverscroll, 1647 const ScreenPoint& aPanDistance); 1648 1649 /** 1650 * Try to overscroll by 'aOverscroll'. 1651 * If we are pannable on a particular axis, that component of 'aOverscroll' 1652 * is transferred to any existing overscroll. 1653 */ 1654 void OverscrollBy(ParentLayerPoint& aOverscroll); 1655 1656 /* =================================================================== 1657 * The functions and members in this section are used to maintain the 1658 * area that this APZC instance is responsible for. This is used when 1659 * hit-testing to see which APZC instance should handle touch events. 1660 */ 1661 public: SetAncestorTransform(const AncestorTransform & aAncestorTransform)1662 void SetAncestorTransform(const AncestorTransform& aAncestorTransform) { 1663 mAncestorTransform = aAncestorTransform; 1664 } 1665 GetAncestorTransform()1666 Matrix4x4 GetAncestorTransform() const { 1667 return mAncestorTransform.CombinedTransform(); 1668 } 1669 AncestorTransformContainsPerspective()1670 bool AncestorTransformContainsPerspective() const { 1671 return mAncestorTransform.ContainsPerspectiveTransform(); 1672 } 1673 1674 // Return the perspective transform component of the ancestor transform. GetAncestorTransformPerspective()1675 Matrix4x4 GetAncestorTransformPerspective() const { 1676 return mAncestorTransform.GetPerspectiveTransform(); 1677 } 1678 1679 // Returns whether or not this apzc contains the given screen point within 1680 // its composition bounds. 1681 bool Contains(const ScreenIntPoint& aPoint) const; 1682 1683 bool IsInOverscrollGutter(const ScreenPoint& aPoint) const; 1684 bool IsInOverscrollGutter(const ParentLayerPoint& aPoint) const; 1685 1686 bool IsOverscrolled() const; 1687 1688 private: 1689 bool IsInInvalidOverscroll() const; 1690 1691 public: 1692 bool IsInPanningState() const; 1693 1694 private: 1695 /* This is the cumulative CSS transform for all the layers from (and 1696 * including) the parent APZC down to (but excluding) this one, and excluding 1697 * any perspective transforms. */ 1698 AncestorTransform mAncestorTransform; 1699 1700 /* =================================================================== 1701 * The functions and members in this section are used for sharing the 1702 * FrameMetrics across processes for the progressive tiling code. 1703 */ 1704 private: 1705 /* Unique id assigned to each APZC. Used with ViewID to uniquely identify 1706 * shared FrameMeterics used in progressive tile painting. */ 1707 const uint32_t mAPZCId; 1708 1709 RefPtr<ipc::SharedMemoryBasic> mSharedFrameMetricsBuffer; 1710 CrossProcessMutex* mSharedLock; 1711 /** 1712 * Called when ever Metrics() is updated so that if it is being 1713 * shared with the content process the shared FrameMetrics may be updated. 1714 */ 1715 void UpdateSharedCompositorFrameMetrics(); 1716 /** 1717 * Create a shared memory buffer for containing the FrameMetrics and 1718 * a CrossProcessMutex that may be shared with the content process 1719 * for use in progressive tiled update calculations. 1720 */ 1721 void ShareCompositorFrameMetrics(); 1722 1723 /* =================================================================== 1724 * The functions and members in this section are used for testing 1725 * and assertion purposes only. 1726 */ 1727 public: 1728 /** 1729 * Gets whether this APZC has performed async key scrolling. 1730 */ TestHasAsyncKeyScrolled()1731 bool TestHasAsyncKeyScrolled() const { return mTestHasAsyncKeyScrolled; } 1732 1733 /** 1734 * Set an extra offset for testing async scrolling. 1735 */ 1736 void SetTestAsyncScrollOffset(const CSSPoint& aPoint); 1737 /** 1738 * Set an extra offset for testing async scrolling. 1739 */ 1740 void SetTestAsyncZoom(const LayerToParentLayerScale& aZoom); 1741 MarkAsyncTransformAppliedToContent()1742 void MarkAsyncTransformAppliedToContent() { 1743 mAsyncTransformAppliedToContent = true; 1744 } 1745 GetAsyncTransformAppliedToContent()1746 bool GetAsyncTransformAppliedToContent() const { 1747 return mAsyncTransformAppliedToContent; 1748 } 1749 GetLayersId()1750 LayersId GetLayersId() const { return mLayersId; } 1751 IsAsyncZooming()1752 bool IsAsyncZooming() const { 1753 RecursiveMutexAutoLock lock(mRecursiveMutex); 1754 return mState == PINCHING || mState == ANIMATING_ZOOM; 1755 } 1756 1757 private: 1758 // The timestamp of the latest touch start event. 1759 TimeStamp mTouchStartTime; 1760 // The time duration between mTouchStartTime and the touchmove event that 1761 // started the pan (the touchmove event that transitioned this APZC from the 1762 // TOUCHING state to one of the PANNING* states). Only valid while this APZC 1763 // is in a panning state. 1764 TimeDuration mTouchStartRestingTimeBeforePan; 1765 Maybe<ParentLayerCoord> mMinimumVelocityDuringPan; 1766 // Extra offset to add to the async scroll position for testing 1767 CSSPoint mTestAsyncScrollOffset; 1768 // Extra zoom to include in the aync zoom for testing 1769 LayerToParentLayerScale mTestAsyncZoom; 1770 uint8_t mTestAttributeAppliers; 1771 // Flag to track whether or not the APZ transform is not used. This 1772 // flag is recomputed for every composition frame. 1773 bool mAsyncTransformAppliedToContent; 1774 // Flag to track whether or not this APZC has ever async key scrolled. 1775 bool mTestHasAsyncKeyScrolled; 1776 1777 /* =================================================================== 1778 * The functions and members in this section are used for checkerboard 1779 * recording. 1780 */ 1781 private: 1782 // Helper function to update the in-progress checkerboard event, if any. 1783 void UpdateCheckerboardEvent(const MutexAutoLock& aProofOfLock, 1784 uint32_t aMagnitude); 1785 1786 // Mutex protecting mCheckerboardEvent 1787 Mutex mCheckerboardEventLock; 1788 // This is created when this APZC instance is first included as part of a 1789 // composite. If a checkerboard event takes place, this is destroyed at the 1790 // end of the event, and a new one is created on the next composite. 1791 UniquePtr<CheckerboardEvent> mCheckerboardEvent; 1792 // This is used to track the total amount of time that we could reasonably 1793 // be checkerboarding. Combined with other info, this allows us to 1794 // meaningfully say how frequently users actually encounter checkerboarding. 1795 PotentialCheckerboardDurationTracker mPotentialCheckerboardTracker; 1796 1797 /* =================================================================== 1798 * The functions in this section are used for CSS scroll snapping. 1799 */ 1800 1801 // If moving |aStartPosition| by |aDelta| should trigger scroll snapping, 1802 // adjust |aDelta| to reflect the snapping (that is, make it a delta that will 1803 // take us to the desired snap point). The delta is interpreted as being 1804 // relative to |aStartPosition|, and if a target snap point is found, 1805 // |aStartPosition| is also updated, to the value of the snap point. 1806 // |aUnit| affects the snapping behaviour (see ScrollSnapUtils:: 1807 // GetSnapPointForDestination). 1808 // Returns true iff. a target snap point was found. 1809 bool MaybeAdjustDeltaForScrollSnapping(ScrollUnit aUnit, 1810 ParentLayerPoint& aDelta, 1811 CSSPoint& aStartPosition); 1812 1813 // A wrapper function of MaybeAdjustDeltaForScrollSnapping for 1814 // ScrollWheelInput. 1815 bool MaybeAdjustDeltaForScrollSnappingOnWheelInput( 1816 const ScrollWheelInput& aEvent, ParentLayerPoint& aDelta, 1817 CSSPoint& aStartPosition); 1818 1819 bool MaybeAdjustDestinationForScrollSnapping(const KeyboardInput& aEvent, 1820 CSSPoint& aDestination); 1821 1822 // Snap to a snap position nearby the current scroll position, if appropriate. 1823 void ScrollSnap(); 1824 1825 // Snap to a snap position nearby the destination predicted based on the 1826 // current velocity, if appropriate. 1827 void ScrollSnapToDestination(); 1828 1829 // Snap to a snap position nearby the provided destination, if appropriate. 1830 void ScrollSnapNear(const CSSPoint& aDestination); 1831 1832 // Find a snap point near |aDestination| that we should snap to. 1833 // Returns the snap point if one was found, or an empty Maybe otherwise. 1834 // |aUnit| affects the snapping behaviour (see ScrollSnapUtils:: 1835 // GetSnapPointForDestination). It should generally be determined by the 1836 // type of event that's triggering the scroll. 1837 Maybe<CSSPoint> FindSnapPointNear(const CSSPoint& aDestination, 1838 ScrollUnit aUnit); 1839 }; 1840 1841 } // namespace layers 1842 } // namespace mozilla 1843 1844 #endif // mozilla_layers_PanZoomController_h 1845