tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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