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