APZCTreeManager.h (51208B)
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_APZCTreeManager_h 8 #define mozilla_layers_APZCTreeManager_h 9 10 #include <unordered_map> // for std::unordered_map 11 12 #include "FocusState.h" // for FocusState 13 #include "HitTestingTreeNode.h" // for HitTestingTreeNodeAutoLock 14 #include "IAPZHitTester.h" // for IAPZHitTester::HitTestResult 15 #include "gfxPoint.h" // for gfxPoint 16 #include "mozilla/Assertions.h" // for MOZ_ASSERT_HELPER2 17 #include "mozilla/DataMutex.h" // for DataMutex 18 #include "mozilla/gfx/CompositorHitTestInfo.h" 19 #include "mozilla/gfx/Logging.h" // for gfx::TreeLog 20 #include "mozilla/gfx/Matrix.h" // for Matrix4x4 21 #include "mozilla/layers/APZInputBridge.h" // for APZInputBridge 22 #include "mozilla/layers/APZUtils.h" // for AsyncTransformComponents 23 #include "mozilla/layers/CompositorScrollUpdate.h" // for CompositorScrollUpdate 24 #include "mozilla/layers/IAPZCTreeManager.h" // for IAPZCTreeManager 25 #include "mozilla/layers/PWebRenderBridgeParent.h" 26 #include "mozilla/layers/ScrollbarData.h" 27 #include "mozilla/layers/LayersTypes.h" 28 #include "mozilla/layers/KeyboardMap.h" // for KeyboardMap 29 #include "mozilla/layers/TouchCounter.h" // for TouchCounter 30 #include "mozilla/layers/ZoomConstraints.h" // for ZoomConstraints 31 #include "mozilla/webrender/webrender_ffi.h" 32 #include "mozilla/RecursiveMutex.h" // for RecursiveMutex 33 #include "mozilla/RefPtr.h" // for RefPtr 34 #include "mozilla/TimeStamp.h" // for mozilla::TimeStamp 35 #include "mozilla/UniquePtr.h" // for UniquePtr 36 #include "nsCOMPtr.h" // for already_AddRefed 37 #include "nsTArray.h" 38 #include "VsyncSource.h" 39 40 namespace mozilla { 41 class MultiTouchInput; 42 43 namespace dom { 44 enum class InteractiveWidget : uint8_t; 45 } // namespace dom 46 47 namespace wr { 48 class TransactionWrapper; 49 class WebRenderAPI; 50 } // namespace wr 51 52 namespace layers { 53 54 class Layer; 55 class AsyncPanZoomController; 56 class APZCTreeManagerParent; 57 class APZSampler; 58 class APZTestData; 59 class APZUpdater; 60 class CompositorBridgeParent; 61 class MatrixMessage; 62 class OverscrollHandoffChain; 63 struct OverscrollHandoffState; 64 class FocusTarget; 65 struct FlingHandoffState; 66 class InputQueue; 67 class GeckoContentController; 68 class HitTestingTreeNode; 69 class SampleTime; 70 class WebRenderScrollDataWrapper; 71 struct AncestorTransform; 72 struct ScrollThumbData; 73 struct ZoomTarget; 74 75 /** 76 * ****************** NOTE ON LOCK ORDERING IN APZ ************************** 77 * 78 * To avoid deadlock, APZ imposes and respects a global ordering on threads 79 * and locks relevant to APZ. 80 * 81 * Please see the "Threading / Locking Overview" section of 82 * gfx/docs/AsyncPanZoom.rst (hosted in rendered form at 83 * https://firefox-source-docs.mozilla.org/gfx/gfx/AsyncPanZoom.html#threading-locking-overview) 84 * for what the ordering is, and what are the rules for respecting it. 85 * ************************************************************************** 86 */ 87 88 /** 89 * This class manages the tree of AsyncPanZoomController instances. There is one 90 * instance of this class owned by each CompositorBridgeParent, and it contains 91 * as many AsyncPanZoomController instances as there are scrollable container 92 * layers. This class generally lives on the updater thread, although some 93 * functions may be called from other threads as noted; thread safety is ensured 94 * internally. 95 * 96 * The bulk of the work of this class happens as part of the 97 * UpdateHitTestingTree function, which is when a layer tree update is received 98 * by the compositor. This function walks through the layer tree and creates a 99 * tree of HitTestingTreeNode instances to match the layer tree and for use in 100 * hit-testing on the controller thread. APZC instances may be preserved across 101 * calls to this function if the corresponding layers are still present in the 102 * layer tree. 103 * 104 * The other functions on this class are used by various pieces of client code 105 * to notify the APZC instances of events relevant to them. This includes, for 106 * example, user input events that drive panning and zooming, changes to the 107 * scroll viewport area, and changes to pan/zoom constraints. 108 * 109 * Note that the ClearTree function MUST be called when this class is no longer 110 * needed; see the method documentation for details. 111 * 112 * Behaviour of APZ is controlled by a number of preferences shown 113 * \ref APZCPrefs "here". 114 */ 115 class APZCTreeManager : public IAPZCTreeManager, public APZInputBridge { 116 typedef mozilla::layers::AllowedTouchBehavior AllowedTouchBehavior; 117 typedef mozilla::layers::AsyncDragMetrics AsyncDragMetrics; 118 using HitTestResult = IAPZHitTester::HitTestResult; 119 120 /* 121 * A result from APZCTreeManager::FindHandoffParent. 122 */ 123 struct TargetApzcForNodeResult { 124 // The APZC to handoff overscroll to. 125 AsyncPanZoomController* mApzc; 126 // Targeting a document's root APZC from content fixed to the document. 127 bool mIsFixed; 128 }; 129 130 // Helper struct to hold some state while we build the hit-testing tree. The 131 // sole purpose of this struct is to shorten the argument list to 132 // UpdateHitTestingTree. All the state that we don't need to 133 // push on the stack during recursion and pop on unwind is stored here. 134 struct TreeBuildingState; 135 136 public: 137 static mozilla::LazyLogModule sLog; 138 139 static already_AddRefed<APZCTreeManager> Create( 140 LayersId aRootLayersId, UniquePtr<IAPZHitTester> aHitTester = nullptr); 141 void SetSampler(APZSampler* aSampler); 142 void SetUpdater(APZUpdater* aUpdater); 143 144 /** 145 * Notifies this APZCTreeManager that the associated compositor is now 146 * responsible for managing another layers id, which got moved over from 147 * some other compositor. That other compositor's APZCTreeManager is also 148 * provided. This allows APZCTreeManager to transfer any necessary state 149 * from the old APZCTreeManager related to that layers id. 150 * This function must be called on the updater thread. 151 */ 152 void NotifyLayerTreeAdopted(LayersId aLayersId, 153 const RefPtr<APZCTreeManager>& aOldTreeManager); 154 155 /** 156 * Notifies this APZCTreeManager that a layer tree being managed by the 157 * associated compositor has been removed/destroyed. Note that this does 158 * NOT get called during shutdown situations, when the root layer tree is 159 * also getting destroyed. 160 * This function must be called on the updater thread. 161 */ 162 void NotifyLayerTreeRemoved(LayersId aLayersId); 163 164 /** 165 * Rebuild the focus state based on the focus target from the layer tree 166 * update that just occurred. This must be called on the updater thread. 167 * 168 * @param aRootLayerTreeId The layer tree ID of the root layer corresponding 169 * to this APZCTreeManager 170 * @param aOriginatingLayersId The layer tree ID of the layer corresponding to 171 * this layer tree update. 172 */ 173 void UpdateFocusState(LayersId aRootLayerTreeId, 174 LayersId aOriginatingLayersId, 175 const FocusTarget& aFocusTarget); 176 177 /** 178 * Rebuild the hit-testing tree based on an incoming WebRender transaction. 179 * Preserve nodes and APZC instances where possible, but retire those whose 180 * layers are no longer in the layer tree. 181 * (Note: "layer tree" here refers to the tree of WebRenderLayerScrollData 182 * nodes sent as part of a WebRender transaction.) 183 * 184 * This must be called on the updater thread. 185 * 186 * @param aRoot The root of the (full) layer tree 187 * @param aOriginatingLayersId The layers id of the subtree that triggered 188 * this repaint. 189 * @param aPaintSequenceNumber The sequence number of the paint that triggered 190 * this layer update. Note that every child 191 * process' layer subtree has its own sequence 192 * numbers. 193 * @return a vector of LayersId processed in UpdateHitTestingTree. 194 */ 195 std::vector<LayersId> UpdateHitTestingTree( 196 const WebRenderScrollDataWrapper& aRoot, LayersId aOriginatingLayersId, 197 uint32_t aPaintSequenceNumber); 198 199 /** 200 * Called from the sampler thread. This function populates the provided 201 * transaction with any async scroll offsets needed. It also advances APZ 202 * animations to the specified sample time, and requests another composite if 203 * there are still active animations. 204 */ 205 void SampleForWebRender(const Maybe<VsyncId>& aVsyncId, 206 wr::TransactionWrapper& aTxn, 207 const SampleTime& aSampleTime); 208 209 /** 210 * Refer to the documentation of APZInputBridge::ReceiveInputEvent() and 211 * APZEventResult. 212 */ 213 APZEventResult ReceiveInputEvent( 214 InputData& aEvent, 215 InputBlockCallback&& aCallback = InputBlockCallback()) override; 216 217 /** 218 * Set the keyboard shortcuts to use for translating keyboard events. 219 */ 220 void SetKeyboardMap(const KeyboardMap& aKeyboardMap) override; 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. |aRect| must be given in CSS pixels, relative to the document. 226 * |aFlags| is a combination of the ZoomToRectBehavior enum values. 227 */ 228 void ZoomToRect(const ScrollableLayerGuid& aGuid, 229 const ZoomTarget& aZoomTarget, 230 const uint32_t aFlags = DEFAULT_BEHAVIOR) override; 231 232 /** 233 * If we have touch listeners, this should always be called when we know 234 * definitively whether or not content has preventDefaulted any touch events 235 * that have come in. If |aPreventDefault| is true, any touch events in the 236 * queue will be discarded. This function must be called on the controller 237 * thread. 238 */ 239 void ContentReceivedInputBlock(uint64_t aInputBlockId, 240 bool aPreventDefault) override; 241 242 /** 243 * When the event regions code is enabled, this function should be invoked to 244 * to confirm the target of the input block. This is only needed in cases 245 * where the initial input event of the block hit a dispatch-to-content region 246 * but is safe to call for all input blocks. 247 * The different elements in the array of targets correspond to the targets 248 * for the different touch points. In the case where the touch point has no 249 * target, or the target is not a scrollable frame, the target's |mScrollId| 250 * should be set to ScrollableLayerGuid::NULL_SCROLL_ID. 251 * Note: For mouse events that start a scrollbar drag, both SetTargetAPZC() 252 * and StartScrollbarDrag() will be called, and the calls may happen 253 * in either order. That's fine - whichever arrives first will confirm 254 * the block, and StartScrollbarDrag() will fill in the drag metrics. 255 * If the block is confirmed before we have drag metrics, some events 256 * in the drag block may be handled as no-ops until the drag metrics 257 * arrive. 258 */ 259 void SetTargetAPZC(uint64_t aInputBlockId, 260 const nsTArray<ScrollableLayerGuid>& aTargets) override; 261 262 /** 263 * Updates any zoom constraints contained in the <meta name="viewport"> tag. 264 * If the |aConstraints| is Nothing() then previously-provided constraints for 265 * the given |aGuid| are cleared. 266 */ 267 void UpdateZoomConstraints( 268 const ScrollableLayerGuid& aGuid, 269 const Maybe<ZoomConstraints>& aConstraints) override; 270 271 /** 272 * Calls Destroy() on all APZC instances attached to the tree, and resets the 273 * tree back to empty. This function must be called exactly once during the 274 * lifetime of this APZCTreeManager, when this APZCTreeManager is no longer 275 * needed. Failing to call this function may prevent objects from being freed 276 * properly. 277 * This must be called on the updater thread. 278 */ 279 void ClearTree(); 280 281 /** 282 * Sets the dpi value used by all AsyncPanZoomControllers attached to this 283 * tree manager. 284 * DPI defaults to 160 if not set using SetDPI() at any point. 285 */ 286 void SetDPI(float aDpiValue) override; 287 288 /** 289 * Returns the current dpi value in use. 290 */ 291 float GetDPI() const; 292 293 /** 294 * Find the hit testing node for the scrollbar thumb that matches these 295 * drag metrics. Initializes aOutThumbNode with the node, if there is one. 296 */ 297 void FindScrollThumbNode(const AsyncDragMetrics& aDragMetrics, 298 LayersId aLayersId, 299 HitTestingTreeNodeAutoLock& aOutThumbNode); 300 301 /** 302 * Sets allowed touch behavior values for current touch-session for specific 303 * input block (determined by aInputBlock). 304 * Should be invoked by the widget. Each value of the aValues arrays 305 * corresponds to the different touch point that is currently active. 306 * Must be called after receiving the TOUCH_START event that starts the 307 * touch-session. 308 */ 309 void SetAllowedTouchBehavior( 310 uint64_t aInputBlockId, 311 const nsTArray<TouchBehaviorFlags>& aValues) override; 312 313 void SetBrowserGestureResponse(uint64_t aInputBlockId, 314 BrowserGestureResponse aResponse) override; 315 316 /** 317 * This is a callback for AsyncPanZoomController to call when it wants to 318 * scroll in response to a touch-move event, or when it needs to hand off 319 * overscroll to the next APZC. Note that because of scroll grabbing, the 320 * first APZC to scroll may not be the one that is receiving the touch events. 321 * 322 * |aPrev| is the APZC that received the touch events triggering the scroll 323 * (in the case of an initial scroll), or the last APZC to scroll (in the 324 * case of overscroll) 325 * |aStartPoint| and |aEndPoint| are in |aPrev|'s transformed screen 326 * coordinates (i.e. the same coordinates in which touch points are given to 327 * APZCs). The amount of (over)scroll is represented by two points rather 328 * than a displacement because with certain 3D transforms, the same 329 * displacement between different points in transformed coordinates can 330 * represent different displacements in untransformed coordinates. 331 * |aOverscrollHandoffChain| is the overscroll handoff chain used for 332 * determining the order in which scroll should be handed off between 333 * APZCs 334 * |aOverscrollHandoffChainIndex| is the next position in the overscroll 335 * handoff chain that should be scrolled. 336 * 337 * aStartPoint and aEndPoint will be modified depending on how much of the 338 * scroll each APZC consumes. This is to allow the sending APZC to go into 339 * an overscrolled state if no APZC further up in the handoff chain accepted 340 * the entire scroll. 341 * 342 * The function will return true if the entire scroll was consumed, and 343 * false otherwise. As this function also modifies aStartPoint and aEndPoint, 344 * when scroll is consumed, it should always the case that this function 345 * returns true if and only if IsZero(aStartPoint - aEndPoint), using the 346 * modified aStartPoint and aEndPoint after the function returns. 347 * 348 * The way this method works is best illustrated with an example. 349 * Consider three nested APZCs, A, B, and C, with C being the innermost one. 350 * Say B is scroll-grabbing. 351 * The touch events go to C because it's the innermost one (so e.g. taps 352 * should go through C), but the overscroll handoff chain is B -> C -> A 353 * because B is scroll-grabbing. 354 * For convenience I'll refer to the three APZC objects as A, B, and C, and 355 * to the tree manager object as TM. 356 * Here's what happens when C receives a touch-move event: 357 * - C.TrackTouch() calls TM.DispatchScroll() with index = 0. 358 * - TM.DispatchScroll() calls B.AttemptScroll() (since B is at index 0 in 359 * the chain). 360 * - B.AttemptScroll() scrolls B. If there is overscroll, it calls 361 * TM.DispatchScroll() with index = 1. 362 * - TM.DispatchScroll() calls C.AttemptScroll() (since C is at index 1 in 363 * the chain) 364 * - C.AttemptScroll() scrolls C. If there is overscroll, it calls 365 * TM.DispatchScroll() with index = 2. 366 * - TM.DispatchScroll() calls A.AttemptScroll() (since A is at index 2 in 367 * the chain) 368 * - A.AttemptScroll() scrolls A. If there is overscroll, it calls 369 * TM.DispatchScroll() with index = 3. 370 * - TM.DispatchScroll() discards the rest of the scroll as there are no 371 * more elements in the chain. 372 * 373 * Note: this should be used for panning only. For handing off overscroll for 374 * a fling, use DispatchFling(). 375 */ 376 bool DispatchScroll(AsyncPanZoomController* aPrev, 377 ParentLayerPoint& aStartPoint, 378 ParentLayerPoint& aEndPoint, 379 OverscrollHandoffState& aOverscrollHandoffState); 380 381 /** 382 * This is a callback for AsyncPanZoomController to call when it wants to 383 * start a fling in response to a touch-end event, or when it needs to hand 384 * off a fling to the next APZC. Note that because of scroll grabbing, the 385 * first APZC to fling may not be the one that is receiving the touch events. 386 * 387 * @param aApzc the APZC that wants to start or hand off the fling 388 * @param aHandoffState a collection of state about the operation, 389 * which contains the following: 390 * 391 * mVelocity the current velocity of the fling, in |aApzc|'s screen 392 * pixels per millisecond 393 * mChain the chain of APZCs along which the fling 394 * should be handed off 395 * mIsHandoff is true if |aApzc| is handing off an existing fling (in 396 * this case the fling is given to the next APZC in the 397 * handoff chain after |aApzc|), and false is |aApzc| wants 398 * start a fling (in this case the fling is given to the 399 * first APZC in the chain) 400 * 401 * The return value is the "residual velocity", the portion of 402 * |aHandoffState.mVelocity| that was not consumed by APZCs in the 403 * handoff chain doing flings. 404 * The caller can use this value to determine whether it should consume 405 * the excess velocity by going into overscroll. 406 */ 407 ParentLayerPoint DispatchFling(AsyncPanZoomController* aApzc, 408 const FlingHandoffState& aHandoffState); 409 410 void StartScrollbarDrag(const ScrollableLayerGuid& aGuid, 411 const AsyncDragMetrics& aDragMetrics) override; 412 413 bool StartAutoscroll(const ScrollableLayerGuid& aGuid, 414 const ScreenPoint& aAnchorLocation) override; 415 416 void StopAutoscroll(const ScrollableLayerGuid& aGuid) override; 417 418 /* 419 * Build the chain of APZCs that will handle overscroll for a pan starting at 420 * |aInitialTarget|. 421 */ 422 RefPtr<const OverscrollHandoffChain> BuildOverscrollHandoffChain( 423 const RefPtr<AsyncPanZoomController>& aInitialTarget); 424 425 /** 426 * Function used to disable LongTap gestures. 427 * 428 * On slow running tests, drags and touch events can be misinterpreted 429 * as a long tap. This allows tests to disable long tap gesture detection. 430 */ 431 void SetLongTapEnabled(bool aTapGestureEnabled) override; 432 433 APZInputBridge* InputBridge() override { return this; } 434 435 /** 436 * Add a callback to be invoked when |aInputBlockId| is ready for handling. 437 * 438 * Should only be used for input blocks that are not yet ready for handling 439 * at the time this is called. If the input block was already handled, 440 * the callback will never be called. 441 * 442 * Only one callback can be registered for an input block at a time. 443 * Subsequent attempts to register a callback for an input block will be 444 * ignored until the existing callback is triggered. 445 */ 446 void AddInputBlockCallback(uint64_t aInputBlockId, 447 InputBlockCallback&& aCallback); 448 449 // Methods to help process WidgetInputEvents (or manage conversion to/from 450 // InputData) 451 452 void ProcessUnhandledEvent(LayoutDeviceIntPoint* aRefPoint, 453 ScrollableLayerGuid* aOutTargetGuid, 454 uint64_t* aOutFocusSequenceNumber, 455 LayersId* aOutLayersId) override; 456 457 void UpdateWheelTransaction( 458 LayoutDeviceIntPoint aRefPoint, EventMessage aEventMessage, 459 const Maybe<ScrollableLayerGuid>& aTargetGuid) override; 460 461 void MaybeOverrideLayersIdForWheelEvent(InputData& aEvent); 462 463 bool GetAPZTestData(LayersId aLayersId, APZTestData* aOutData); 464 465 /** 466 * Iterates over the hit testing tree, collects LayersIds and associated 467 * transforms from layer coordinate space to root coordinate space, and 468 * sends these over to the main thread of the chrome process. If the provided 469 * |aAncestor| argument is non-null, then only the transforms for layer 470 * subtrees scrolled by the aAncestor (i.e. descendants of aAncestor) will be 471 * sent. 472 */ 473 void SendSubtreeTransformsToChromeMainThread( 474 const AsyncPanZoomController* aAncestor); 475 476 /** 477 * Set fixed layer margins for dynamic toolbar. 478 */ 479 void SetFixedLayerMargins(ScreenIntCoord aTop, ScreenIntCoord aBottom); 480 481 /** 482 * Refer to apz::ComputeTransformForScrollThumb() for a description 483 * of the parameters. 484 */ 485 static LayerToParentLayerMatrix4x4 ComputeTransformForScrollThumb( 486 const LayerToParentLayerMatrix4x4& aCurrentTransform, 487 const gfx::Matrix4x4& aScrollableContentTransform, 488 AsyncPanZoomController* aApzc, const FrameMetrics& aMetrics, 489 const ScrollbarData& aScrollbarData, bool aScrollbarIsDescendant); 490 491 /** 492 * Dispatch a flush complete notification from the repaint thread of the 493 * content controller for the given layers id. 494 */ 495 static void FlushApzRepaints(LayersId aLayersId); 496 497 void EndWheelTransaction( 498 PWebRenderBridgeParent::EndWheelTransactionResolver&& aResolver); 499 500 /** 501 * Mark |aLayersId| as having been moved from the compositor that owns this 502 * tree manager to a compositor that doesn't use APZ. 503 * See |mDetachedLayersIds| for more details. 504 */ 505 void MarkAsDetached(LayersId aLayersId); 506 507 // Assert that the current thread is the sampler thread for this APZCTM. 508 void AssertOnSamplerThread(); 509 // Assert that the current thread is the updater thread for this APZCTM. 510 void AssertOnUpdaterThread(); 511 512 // Returns a pointer to the WebRenderAPI this APZCTreeManager is for. 513 // This might be null (for example, during GTests). 514 already_AddRefed<wr::WebRenderAPI> GetWebRenderAPI() const; 515 516 protected: 517 APZCTreeManager(LayersId aRootLayersId, UniquePtr<IAPZHitTester> aHitTester); 518 519 void Init(); 520 521 // Protected destructor, to discourage deletion outside of Release(): 522 virtual ~APZCTreeManager(); 523 524 APZSampler* GetSampler() const; 525 APZUpdater* GetUpdater() const; 526 527 bool AdvanceAnimationsInternal(const MutexAutoLock& aProofOfMapLock, 528 const SampleTime& aSampleTime) 529 MOZ_REQUIRES(mMapLock); 530 531 // We need to allow APZUpdater to lock and unlock this tree during a WR 532 // scene swap. We do this using private helpers to avoid exposing these 533 // functions to the world. 534 private: 535 friend class APZUpdater; 536 void LockTree() MOZ_CAPABILITY_ACQUIRE(mTreeLock); 537 void UnlockTree() MOZ_CAPABILITY_RELEASE(mTreeLock); 538 539 // Protected hooks for gtests subclass 540 virtual already_AddRefed<AsyncPanZoomController> NewAPZCInstance( 541 LayersId aLayersId, GeckoContentController* aController); 542 543 void SetFixedLayerMarginsOnRootContentApzcs( 544 const RecursiveMutexAutoLock& aProofOfTreeLock) MOZ_REQUIRES(mTreeLock); 545 546 public: 547 // Public hook for gtests subclass 548 virtual SampleTime GetFrameTime(); 549 550 // Also used for controlling time during tests 551 void SetTestSampleTime(const Maybe<TimeStamp>& aTime); 552 553 private: 554 mutable DataMutex<Maybe<TimeStamp>> mTestSampleTime; 555 CopyableTArray<MatrixMessage> mLastMessages; 556 557 public: 558 /* Some helper functions to find an APZC given some identifying input. These 559 functions lock the tree of APZCs while they find the right one, and then 560 return an addref'd pointer to it. This allows caller code to just use the 561 target APZC without worrying about it going away. These are public for 562 testing code and generally should not be used by other production code. 563 */ 564 RefPtr<HitTestingTreeNode> GetRootNode() const; 565 HitTestResult GetTargetAPZC(const ScreenPoint& aPoint); 566 already_AddRefed<AsyncPanZoomController> GetTargetAPZC( 567 const LayersId& aLayersId, 568 const ScrollableLayerGuid::ViewID& aScrollId) const; 569 // GetTargetAPZC() should be marked MOZ_REQUIRES(mMapLock) but it's called by 570 // code external to this class (APZSampler.cpp) via CallWithMapLock(). 571 // We can't place a MOZ_REQUIRES(mMapLock) annotation on a method of another 572 // class, so we have a runtime assertion about holding mMapLock in the 573 // function body instead. 574 already_AddRefed<AsyncPanZoomController> GetTargetAPZC( 575 const LayersId& aLayersId, const ScrollableLayerGuid::ViewID& aScrollId, 576 const MutexAutoLock& aProofOfMapLock) const; 577 ScreenToParentLayerMatrix4x4 GetScreenToApzcTransform( 578 const AsyncPanZoomController* aApzc) const; 579 ParentLayerToScreenMatrix4x4 GetApzcToGeckoTransformForHit( 580 HitTestResult& aHitResult) const; 581 ParentLayerToScreenMatrix4x4 GetApzcToGeckoTransform( 582 const AsyncPanZoomController* aApzc, 583 const AsyncTransformComponents& aComponents) const; 584 585 /* 586 * A common utility function used for GetApzcToGeckoTransform and 587 * GetOopifApzcToRootContentApzcTransform. 588 * 589 * NOTE: The matrix returned by this function can NOT be used to convert 590 * metrics in |aStartApzc| to |aStopApzc|. If you want the conversion matrix, 591 * you will have to use either GetApzcToGeckoTransform or 592 * GetOopifApzcToRootContentApzcTransform. 593 */ 594 ParentLayerToParentLayerMatrix4x4 GetApzcToApzcTransform( 595 const AsyncPanZoomController* aStartApzc, 596 const AsyncPanZoomController* aStopApzc, 597 const AsyncTransformComponents& aComponents) const; 598 599 /* 600 * Returns the matrix which transforms coordinates relative to the layout 601 * viewport of |aApzc|, to be relative to the document origin of the root 602 * content APZC of |aApzc|. 603 * |aApzc| must be the root APZC of an out-of-process iframe. 604 */ 605 CSSToCSSMatrix4x4 GetOopifToRootContentTransform( 606 AsyncPanZoomController* aApzc) const; 607 608 /** 609 * Convert the given |aRect| in the document coordinates of |aApzc| to the top 610 * level document coordinates. 611 * |aApzc| must be an in-process root APZC. 612 */ 613 CSSRect ConvertRectInApzcToRoot(AsyncPanZoomController* aApzc, 614 const CSSRect& aRect) const; 615 616 ScreenPoint GetCurrentMousePosition() const; 617 void SetCurrentMousePosition(const ScreenPoint& aNewPos); 618 619 /** 620 * Convert a screen point of an event targeting |aApzc| to Gecko 621 * coordinates. 622 */ 623 Maybe<ScreenIntPoint> ConvertToGecko(const ScreenIntPoint& aPoint, 624 AsyncPanZoomController* aApzc); 625 626 /** 627 * Find the zoomable APZC in the same layer subtree (i.e. with the same 628 * layers id) as the given APZC. 629 */ 630 already_AddRefed<AsyncPanZoomController> FindZoomableApzc( 631 AsyncPanZoomController* aStart) const; 632 633 AsyncPanZoomController* FindRootApzcFor(LayersId aLayersId) const; 634 635 ScreenMargin GetCompositorFixedLayerMargins() const; 636 637 void AdjustEventPointForDynamicToolbar(ScreenIntPoint& aEventPoint, 638 const HitTestResult& aHit); 639 640 APZScrollGeneration NewAPZScrollGeneration() { 641 // In the production code this function gets only called from the sampler 642 // thread but in tests using nsIDOMWindowUtils.setAsyncScrollOffset this 643 // function gets called from the controller thread so we need to lock the 644 // mutex for this counter. 645 MutexAutoLock lock(mScrollGenerationLock); 646 return mScrollGenerationCounter.NewAPZGeneration(); 647 } 648 649 template <typename Callback> 650 void CallWithMapLock(Callback& aCallback) { 651 MutexAutoLock lock(mMapLock); 652 aCallback(lock); 653 } 654 655 private: 656 using GuidComparator = ScrollableLayerGuid::Comparator; 657 using ScrollNode = WebRenderScrollDataWrapper; 658 659 /* Helpers */ 660 661 void AttachNodeToTree(HitTestingTreeNode* aNode, HitTestingTreeNode* aParent, 662 HitTestingTreeNode* aNextSibling) 663 MOZ_REQUIRES(mTreeLock); 664 already_AddRefed<AsyncPanZoomController> GetTargetAPZC( 665 const ScrollableLayerGuid& aGuid); 666 already_AddRefed<HitTestingTreeNode> GetTargetNode( 667 const ScrollableLayerGuid& aGuid, GuidComparator aComparator) const; 668 HitTestingTreeNode* FindTargetNode(HitTestingTreeNode* aNode, 669 const ScrollableLayerGuid& aGuid, 670 GuidComparator aComparator); 671 TargetApzcForNodeResult GetTargetApzcForNode(const HitTestingTreeNode* aNode); 672 TargetApzcForNodeResult FindHandoffParent( 673 const AsyncPanZoomController* aApzc); 674 675 // An optimized version of GetTargetAPZC for mouse input. 676 HitTestResult GetTargetAPZCForMouseInput(const MouseInput& aMouseInput); 677 678 /** 679 * Find the root __content__ APZC for |aLayersId|. 680 * If |aLayersId| is NOT for the LayersId for the root content, this function 681 * returns nullptr. 682 * 683 * NOTE: Only the top-level content document will have a root content APZC. 684 */ 685 HitTestingTreeNode* FindRootNodeForLayersId(LayersId aLayersId) const; 686 AsyncPanZoomController* FindRootContentApzcForLayersId( 687 LayersId aLayersId) const; 688 already_AddRefed<AsyncPanZoomController> GetZoomableTarget( 689 AsyncPanZoomController* aApzc1, AsyncPanZoomController* aApzc2) const; 690 already_AddRefed<AsyncPanZoomController> CommonAncestor( 691 AsyncPanZoomController* aApzc1, AsyncPanZoomController* aApzc2) const; 692 693 struct FixedPositionInfo; 694 struct StickyPositionInfo; 695 696 // Returns true if |aFixedInfo| represents a layer that is fixed to the root 697 // content APZC. 698 bool IsFixedToRootContent(const FixedPositionInfo& aFixedInfo, 699 const MutexAutoLock& aProofOfMapLock) const 700 MOZ_REQUIRES(mMapLock); 701 702 // Returns the vertical sides of |aNode| that are stuck to the root content. 703 // The map lock is required within these functions; if the map lock is already 704 // being held by the caller, the second overload should be used. If the map 705 // lock is not being held at the call site, the first overload should be used. 706 SideBits SidesStuckToRootContent(const HitTestingTreeNode* aNode, 707 AsyncTransformConsumer aMode) const; 708 SideBits SidesStuckToRootContent(const StickyPositionInfo& aStickyInfo, 709 AsyncTransformConsumer aMode, 710 const MutexAutoLock& aProofOfMapLock) const 711 MOZ_REQUIRES(mMapLock); 712 713 /** 714 * Perform hit testing for a touch-start event. 715 * 716 * @param aEvent The touch-start event. 717 * 718 * The remaining parameters are out-parameter used to communicate additional 719 * return values: 720 * 721 * @param aOutTouchBehaviors 722 * The touch behaviours that should be allowed for this touch block. 723 724 * @return The results of the hit test, including the APZC that was hit. 725 */ 726 HitTestResult GetTouchInputBlockAPZC( 727 const MultiTouchInput& aEvent, 728 nsTArray<TouchBehaviorFlags>* aOutTouchBehaviors); 729 730 /** 731 * A helper structure for use by ReceiveInputEvent() and its helpers. 732 */ 733 struct InputHandlingState { 734 // A reference to the event being handled. 735 InputData& mEvent; 736 737 // The value that will be returned by ReceiveInputEvent(). 738 APZEventResult mResult; 739 740 // If we performed a hit-test while handling this input event, or 741 // reused the result of a previous hit-test in the input block, 742 // this is populated with the result of the hit test. 743 HitTestResult mHit; 744 745 // Called at the end of ReceiveInputEvent() to perform any final 746 // computations, and then return mResult. 747 // If the event will have a delayed result then this takes care of adding 748 // the specified callback to the APZCTreeManager. 749 APZEventResult Finish(APZCTreeManager& aTreeManager, 750 InputBlockCallback&& aCallback); 751 }; 752 753 void ProcessTouchInput(InputHandlingState& aState, MultiTouchInput& aInput); 754 /** 755 * Given a mouse-down event that hit a scroll thumb node, set up APZ 756 * dragging of the scroll thumb. 757 * 758 * Must be called after the mouse event has been sent to InputQueue. 759 * 760 * @param aMouseInput The mouse-down event. 761 * @param aScrollThumbNode Tthe scroll thumb node that was hit. 762 * @param aApzc 763 * The APZC for the scroll frame scrolled by the scroll thumb, if that 764 * scroll frame is layerized. (A thumb can be layerized without its 765 * target scroll frame being layerized.) Otherwise, an enclosing APZC. 766 */ 767 void SetupScrollbarDrag(MouseInput& aMouseInput, 768 const HitTestingTreeNodeAutoLock& aScrollThumbNode, 769 AsyncPanZoomController* aApzc); 770 /** 771 * Process a touch event that's part of a scrollbar touch-drag gesture. 772 * 773 * @param aInput The touch event. 774 * @param aScrollThumbNode 775 * If this is the touch-start event, the node representing the scroll 776 * thumb we are starting to drag. Otherwise nullptr. 777 * @param aHitInfo 778 * The hit-test flags for the touch input. 779 * @return See ReceiveInputEvent() for what the return value means. 780 */ 781 APZEventResult ProcessTouchInputForScrollbarDrag( 782 MultiTouchInput& aInput, 783 const HitTestingTreeNodeAutoLock& aScrollThumbNode, 784 const gfx::CompositorHitTestInfo& aHitInfo); 785 void FlushRepaintsToClearScreenToGeckoTransform(); 786 787 void SynthesizePinchGestureFromMouseWheel( 788 const ScrollWheelInput& aWheelInput, 789 const RefPtr<AsyncPanZoomController>& aTarget); 790 791 already_AddRefed<HitTestingTreeNode> RecycleOrCreateNode( 792 const RecursiveMutexAutoLock& aProofOfTreeLock, TreeBuildingState& aState, 793 AsyncPanZoomController* aApzc, LayersId aLayersId); 794 HitTestingTreeNode* PrepareNodeForLayer( 795 const RecursiveMutexAutoLock& aProofOfTreeLock, const ScrollNode& aLayer, 796 const FrameMetrics& aMetrics, LayersId aLayersId, 797 const Maybe<ZoomConstraints>& aZoomConstraints, 798 const AncestorTransform& aAncestorTransform, HitTestingTreeNode* aParent, 799 HitTestingTreeNode* aNextSibling, TreeBuildingState& aState); 800 801 void PrintLayerInfo(const ScrollNode& aLayer); 802 803 void NotifyScrollbarDragInitiated(uint64_t aDragBlockId, 804 const ScrollableLayerGuid& aGuid, 805 ScrollDirection aDirection) const; 806 void NotifyScrollbarDragRejected(const ScrollableLayerGuid& aGuid) const; 807 void NotifyAutoscrollRejected(const ScrollableLayerGuid& aGuid) const; 808 809 // Returns the transform that converts from |aNode|'s coordinates 810 // to the coordinates of |aNode|'s parent in the hit-testing tree. Requires 811 // the caller to hold mTreeLock. 812 LayerToParentLayerMatrix4x4 ComputeTransformForScrollThumbNode( 813 const HitTestingTreeNode* aNode) const MOZ_REQUIRES(mTreeLock); 814 815 // Look up the GeckoContentController for the given layers id. 816 static already_AddRefed<GeckoContentController> GetContentController( 817 LayersId aLayersId); 818 819 using ClippedCompositionBoundsMap = 820 std::unordered_map<ScrollableLayerGuid, ParentLayerRect, 821 ScrollableLayerGuid::HashIgnoringPresShellFn, 822 ScrollableLayerGuid::EqualIgnoringPresShellFn>; 823 // This is a recursive function that populates `aDestMap` with the clipped 824 // composition bounds for the APZC corresponding to `aGuid` and returns those 825 // bounds as a convenience. It recurses to also populate `aDestMap` with that 826 // APZC's ancestors. In order to do this it needs to access mApzcMap 827 // and therefore requires the caller to hold the map lock. 828 ParentLayerRect ComputeClippedCompositionBounds( 829 const MutexAutoLock& aProofOfMapLock, 830 ClippedCompositionBoundsMap& aDestMap, ScrollableLayerGuid aGuid) 831 MOZ_REQUIRES(mMapLock); 832 833 ScreenMargin GetCompositorFixedLayerMargins( 834 const MutexAutoLock& aProofOfMapLock) const MOZ_REQUIRES(mMapLock); 835 836 /** 837 * Compute the translation that should be applied to a layer that's fixed 838 * at |eFixedSides|, to respect the fixed layer margins 839 * |mCompositorFixedLayerMargins|, given that the most recent main thread 840 * paint has taken into account |aGeckoFixedLayerMargins|. 841 */ 842 ScreenPoint ComputeFixedMarginsOffset( 843 const MutexAutoLock& aProofOfMapLock, SideBits aFixedSides, 844 const ScreenMargin& aGeckoFixedLayerMargins) const MOZ_REQUIRES(mMapLock); 845 846 // Accessors for mIsSoftwareKeyboardVisible and mInteractiveWidget which 847 // ensure that we are holding the map lock. 848 bool IsSoftwareKeyboardVisible(const MutexAutoLock& aProofOfMapLock) const 849 MOZ_REQUIRES(mMapLock) { 850 return mIsSoftwareKeyboardVisible; 851 } 852 void SetIsSoftwareKeyboardVisible(bool aIsSoftwareKeyboardVisible, 853 const MutexAutoLock& aProofOfMapLock) 854 MOZ_REQUIRES(mMapLock) { 855 mIsSoftwareKeyboardVisible = aIsSoftwareKeyboardVisible; 856 } 857 dom::InteractiveWidget InteractiveWidgetMode( 858 const MutexAutoLock& aProofOfMapLock) const MOZ_REQUIRES(mMapLock) { 859 return mInteractiveWidget; 860 } 861 void SetInteractiveWidgetMode(dom::InteractiveWidget aInteractiveWidgetMode, 862 const MutexAutoLock& aProofOfMapLock) 863 MOZ_REQUIRES(mMapLock) { 864 mInteractiveWidget = aInteractiveWidgetMode; 865 } 866 867 protected: 868 /* The input queue where input events are held until we know enough to 869 * figure out where they're going. Protected so gtests can access it. 870 */ 871 RefPtr<InputQueue> mInputQueue; 872 873 /** A lock that protects mApzcMap, mScrollThumbInfo, mRootScrollbarInfo, 874 * mFixedPositionInfo, and mStickyPositionInfo. 875 */ 876 mutable mozilla::Mutex mMapLock; 877 878 private: 879 /* Layers id for the root CompositorBridgeParent that owns this 880 * APZCTreeManager. */ 881 LayersId mRootLayersId; 882 883 /* Pointer to the APZSampler instance that is bound to this APZCTreeManager. 884 * The sampler has a RefPtr to this class, and this non-owning raw pointer 885 * back to the APZSampler is nulled out in the sampler's destructor, so this 886 * pointer should always be valid. 887 */ 888 APZSampler* MOZ_NON_OWNING_REF mSampler; 889 /* Pointer to the APZUpdater instance that is bound to this APZCTreeManager. 890 * The updater has a RefPtr to this class, and this non-owning raw pointer 891 * back to the APZUpdater is nulled out in the updater's destructor, so this 892 * pointer should always be valid. 893 */ 894 APZUpdater* MOZ_NON_OWNING_REF mUpdater; 895 896 /* Whenever walking or mutating the tree rooted at mRootNode, mTreeLock must 897 * be held. This lock does not need to be held while manipulating a single 898 * APZC instance in isolation (that is, if its tree pointers are not being 899 * accessed or mutated). The lock also needs to be held when accessing the 900 * mRootNode instance variable, as that is considered part of the APZC tree 901 * management state. 902 * IMPORTANT: See the note about lock ordering at the top of this file. */ 903 mutable mozilla::RecursiveMutex mTreeLock; 904 RefPtr<HitTestingTreeNode> mRootNode MOZ_GUARDED_BY(mTreeLock); 905 906 /* 907 * A set of LayersIds for which APZCTM should only send empty 908 * MatrixMessages via NotifyLayerTransform(). 909 * This is used in cases where a tab has been transferred to a non-APZ 910 * compositor (and thus will not receive MatrixMessages reflecting its new 911 * transforms) and we need to make sure it doesn't get stuck with transforms 912 * from its old tree manager (us). 913 * Acquire mTreeLock before accessing this. 914 */ 915 std::unordered_set<LayersId, LayersId::HashFn> mDetachedLayersIds 916 MOZ_GUARDED_BY(mTreeLock); 917 918 /** 919 * Helper structure to store a bunch of things in mApzcMap so that they can 920 * be used from the sampler thread. 921 */ 922 struct ApzcMapData { 923 // A pointer to the APZC itself 924 RefPtr<AsyncPanZoomController> apzc; 925 // The parent APZC's guid, or Nothing() if there is no parent 926 Maybe<ScrollableLayerGuid> parent; 927 }; 928 929 /** 930 * A map for quick access to get some APZC data by guid, without having to 931 * acquire the tree lock. mMapLock must be acquired while accessing or 932 * modifying mApzcMap. 933 */ 934 std::unordered_map<ScrollableLayerGuid, ApzcMapData, 935 ScrollableLayerGuid::HashIgnoringPresShellFn, 936 ScrollableLayerGuid::EqualIgnoringPresShellFn> 937 mApzcMap MOZ_GUARDED_BY(mMapLock); 938 /** 939 * A helper structure to store all the information needed to compute the 940 * async transform for a scrollthumb on the sampler thread. 941 */ 942 struct ScrollThumbInfo { 943 uint64_t mThumbAnimationId; 944 CSSTransformMatrix mThumbTransform; 945 ScrollbarData mThumbData; 946 ScrollableLayerGuid mTargetGuid; 947 CSSTransformMatrix mTargetTransform; 948 bool mTargetIsAncestor; 949 950 ScrollThumbInfo(const uint64_t& aThumbAnimationId, 951 const CSSTransformMatrix& aThumbTransform, 952 const ScrollbarData& aThumbData, 953 const ScrollableLayerGuid& aTargetGuid, 954 const CSSTransformMatrix& aTargetTransform, 955 bool aTargetIsAncestor) 956 : mThumbAnimationId(aThumbAnimationId), 957 mThumbTransform(aThumbTransform), 958 mThumbData(aThumbData), 959 mTargetGuid(aTargetGuid), 960 mTargetTransform(aTargetTransform), 961 mTargetIsAncestor(aTargetIsAncestor) { 962 MOZ_ASSERT(mTargetGuid.mScrollId == mThumbData.mTargetViewId); 963 } 964 }; 965 /** 966 * This vector gets populated during a layers update. It holds a package of 967 * information needed to compute and set the async transforms on scroll 968 * thumbs. This information is extracted from the HitTestingTreeNodes because 969 * accessing the HitTestingTreeNodes requires holding the tree lock which we 970 * cannot do on the WebRender sampler thread. mScrollThumbInfo, however, can 971 * be accessed while just holding the mMapLock which is safe to do on the 972 * sampler thread. mMapLock must be acquired while accessing or modifying 973 * mScrollThumbInfo. 974 */ 975 std::vector<ScrollThumbInfo> mScrollThumbInfo MOZ_GUARDED_BY(mMapLock); 976 977 /** 978 * A helper structure to store all the information needed to compute the 979 * async transform for a scrollthumb on the sampler thread. 980 */ 981 struct RootScrollbarInfo { 982 uint64_t mScrollbarAnimationId; 983 ScrollDirection mScrollDirection; 984 985 RootScrollbarInfo(const uint64_t& aScrollbarAnimationId, 986 const ScrollDirection aScrollDirection) 987 : mScrollbarAnimationId(aScrollbarAnimationId), 988 mScrollDirection(aScrollDirection) {} 989 }; 990 /** 991 * This vector gets populated during a layers update. It holds a package of 992 * information needed to compute and set the async transforms on root 993 * scrollbars. This information is extracted from the HitTestingTreeNodes 994 * because accessing the HitTestingTreeNodes requires holding the tree lock 995 * which we cannot do on the WebRender sampler thread. mRootScrollbarInfo, 996 * however, can be accessed while just holding the mMapLock which is safe to 997 * do on the sampler thread. 998 * mMapLock must be acquired while accessing or modifying mRootScrollbarInfo. 999 */ 1000 std::vector<RootScrollbarInfo> mRootScrollbarInfo MOZ_GUARDED_BY(mMapLock); 1001 1002 /** 1003 * A helper structure to store all the information needed to compute the 1004 * async transform for a fixed position element on the sampler thread. 1005 */ 1006 struct FixedPositionInfo { 1007 Maybe<uint64_t> mFixedPositionAnimationId; 1008 SideBits mFixedPosSides; 1009 ScrollableLayerGuid::ViewID mFixedPosTarget; 1010 LayersId mLayersId; 1011 1012 explicit FixedPositionInfo(const HitTestingTreeNode* aNode); 1013 }; 1014 /** 1015 * This vector gets populated during a layers update. It holds a package of 1016 * information needed to compute and set the async transforms on fixed 1017 * position content. This information is extracted from the 1018 * HitTestingTreeNodes because accessing the HitTestingTreeNodes requires 1019 * holding the tree lock which we cannot do on the WebRender sampler thread. 1020 * mFixedPositionInfo, however, can be accessed while just holding the 1021 * mMapLock which is safe to do on the sampler thread. mMapLock must be 1022 * acquired while accessing or modifying mFixedPositionInfo. 1023 */ 1024 std::vector<FixedPositionInfo> mFixedPositionInfo MOZ_GUARDED_BY(mMapLock); 1025 1026 /** 1027 * A helper structure to store all the information needed to compute the 1028 * async transform for a sticky position element on the sampler thread. 1029 */ 1030 struct StickyPositionInfo { 1031 Maybe<uint64_t> mStickyPositionAnimationId; 1032 SideBits mFixedPosSides; 1033 ScrollableLayerGuid::ViewID mStickyPosTarget; 1034 LayersId mLayersId; 1035 LayerRectAbsolute mStickyScrollRangeInner; 1036 LayerRectAbsolute mStickyScrollRangeOuter; 1037 1038 explicit StickyPositionInfo(const HitTestingTreeNode* aNode); 1039 }; 1040 /** 1041 * This vector gets populated during a layers update. It holds a package of 1042 * information needed to compute and set the async transforms on sticky 1043 * position content. This information is extracted from the 1044 * HitTestingTreeNodes because accessing the HitTestingTreeNodes requires 1045 * holding the tree lock which we cannot do on the WebRender sampler thread. 1046 * mStickyPositionInfo, however, can be accessed while just holding the 1047 * mMapLock which is safe to do on the sampler thread. mMapLock must be 1048 * acquired while accessing or modifying mStickyPositionInfo. 1049 */ 1050 std::vector<StickyPositionInfo> mStickyPositionInfo MOZ_GUARDED_BY(mMapLock); 1051 1052 /* Holds the zoom constraints for scrollable layers, as determined by the 1053 * the main-thread gecko code. This can only be accessed on the updater 1054 * thread. */ 1055 std::unordered_map<ScrollableLayerGuid, ZoomConstraints, 1056 ScrollableLayerGuid::HashIgnoringPresShellFn, 1057 ScrollableLayerGuid::EqualIgnoringPresShellFn> 1058 mZoomConstraints; 1059 /* A list of keyboard shortcuts to use for translating keyboard inputs into 1060 * keyboard actions. This is gathered on the main thread from XBL bindings. 1061 * This must only be accessed on the controller thread. 1062 */ 1063 KeyboardMap mKeyboardMap; 1064 /* This tracks the focus targets of chrome and content and whether we have 1065 * a current focus target or whether we are waiting for a new confirmation. 1066 */ 1067 FocusState mFocusState; 1068 /* This tracks the hit test result info for the current touch input block. 1069 * In particular, it tracks the target APZC, the hit test flags, and the 1070 * fixed pos sides. This is populated at the start of a touch block based 1071 * on the hit-test result, and used for subsequent touch events in the block. 1072 * This allows touch points to move outside the thing they started on, but 1073 * still have the touch events delivered to the same initial APZC. This will 1074 * only ever be touched on the input delivery thread, and so does not require 1075 * locking. 1076 */ 1077 HitTestResult mTouchBlockHitResult; 1078 /* Sometimes we want to ignore all touches except one. In such cases, this 1079 * is set to the identifier of the touch we are not ignoring; in other cases, 1080 * this is set to -1. 1081 */ 1082 int32_t mRetainedTouchIdentifier; 1083 /* This tracks whether the current input block represents a touch-drag of 1084 * a scrollbar. In this state, touch events are forwarded to content as touch 1085 * events, but converted to mouse events before going into InputQueue and 1086 * being handled by an APZC (to reuse the APZ code for scrollbar dragging 1087 * with a mouse). 1088 */ 1089 bool mInScrollbarTouchDrag; 1090 /* Tracks the number of touch points we are tracking that are currently on 1091 * the screen. */ 1092 TouchCounter mTouchCounter; 1093 /* If a tap gesture event sent directly by widget code (rather than gesture 1094 * detected from touch events by APZ) is being processed, this stores the 1095 * result of hit testing for that tap gesture event. 1096 */ 1097 HitTestResult mTapGestureHitResult; 1098 /* This tracks the hit test result info for the current drag input block of a 1099 * scrollbar initiated by a mousedown. 1100 * This result is used for an optimization to skip hit testing on subsequent 1101 * mousemove events. 1102 */ 1103 HitTestResult mDragBlockHitResult; 1104 /* Stores the current mouse position in screen coordinates. 1105 */ 1106 mutable DataMutex<ScreenPoint> mCurrentMousePosition; 1107 /* Extra margins that should be applied to content that fixed wrt. the 1108 * RCD-RSF, to account for the dynamic toolbar. 1109 * Acquire mMapLock before accessing this. 1110 */ 1111 ScreenMargin mCompositorFixedLayerMargins MOZ_GUARDED_BY(mMapLock); 1112 /* Similar to above |mCompositorFixedLayerMargins|. But this value is the 1113 * margins on the main-thread at the last time position:fixed elements were 1114 * updated during the dynamic toolbar transitions. 1115 * Acquire mMapLock before accessing this. 1116 */ 1117 ScreenMargin mGeckoFixedLayerMargins MOZ_GUARDED_BY(mMapLock); 1118 /* For logging the APZC tree for debugging (enabled by the apz.printtree 1119 * pref). The purpose of using LOG_CRITICAL is so that you don't also need to 1120 * change the gfx.logging.level pref to see the output. */ 1121 gfx::TreeLog<gfx::LOG_CRITICAL> mApzcTreeLog; 1122 1123 class CheckerboardFlushObserver; 1124 friend class CheckerboardFlushObserver; 1125 RefPtr<CheckerboardFlushObserver> mFlushObserver; 1126 1127 // Map from layers id to APZTestData. Accesses and mutations must be 1128 // protected by the mTestDataLock. 1129 std::unordered_map<LayersId, UniquePtr<APZTestData>, LayersId::HashFn> 1130 mTestData; 1131 mutable mozilla::Mutex mTestDataLock; 1132 1133 // This must only be touched on the controller thread. 1134 float mDPI; 1135 1136 friend class IAPZHitTester; 1137 UniquePtr<IAPZHitTester> mHitTester; 1138 1139 // An array of root content APZCs in this tree. 1140 nsTArray<AsyncPanZoomController*> mRootContentApzcs MOZ_GUARDED_BY(mTreeLock); 1141 1142 // NOTE: This ScrollGenerationCounter needs to be per APZCTreeManager since 1143 // the generation is bumped up on the sampler theread which is per 1144 // APZCTreeManager. 1145 ScrollGenerationCounter mScrollGenerationCounter; 1146 mozilla::Mutex mScrollGenerationLock; 1147 1148 // The interactive-widget of the top level content document. 1149 // https://drafts.csswg.org/css-viewport/#interactive-widget-section 1150 // Acquire mMapLock before accessing this. 1151 dom::InteractiveWidget mInteractiveWidget MOZ_GUARDED_BY(mMapLock); 1152 1153 // Whether the software keyboard is visible or not. 1154 // Acquire mMapLock before accessing this. 1155 bool mIsSoftwareKeyboardVisible MOZ_GUARDED_BY(mMapLock); 1156 1157 // Whether there's any OOP iframe in this tree. 1158 // NOTE: This variable needs to be guarded by mTreeLock. 1159 bool mHaveOOPIframes; 1160 }; 1161 1162 } // namespace layers 1163 } // namespace mozilla 1164 1165 #endif // mozilla_layers_PanZoomController_h