Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* This Source Code Form is subject to the terms of the Mozilla Public
3 : * License, v. 2.0. If a copy of the MPL was not distributed with this
4 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 :
6 : #ifndef mozilla_layers_APZCTreeManager_h
7 : #define mozilla_layers_APZCTreeManager_h
8 :
9 : #include <unordered_map> // for std::unordered_map
10 :
11 : #include "gfxPoint.h" // for gfxPoint
12 : #include "mozilla/Assertions.h" // for MOZ_ASSERT_HELPER2
13 : #include "mozilla/gfx/Logging.h" // for gfx::TreeLog
14 : #include "mozilla/gfx/Matrix.h" // for Matrix4x4
15 : #include "mozilla/layers/TouchCounter.h"// for TouchCounter
16 : #include "mozilla/layers/IAPZCTreeManager.h" // for IAPZCTreeManager
17 : #include "mozilla/layers/KeyboardMap.h" // for KeyboardMap
18 : #include "mozilla/layers/FocusState.h" // for FocusState
19 : #include "mozilla/Mutex.h" // for Mutex
20 : #include "mozilla/RefPtr.h" // for RefPtr
21 : #include "mozilla/TimeStamp.h" // for mozilla::TimeStamp
22 : #include "nsCOMPtr.h" // for already_AddRefed
23 :
24 : #if defined(MOZ_WIDGET_ANDROID)
25 : #include "mozilla/layers/AndroidDynamicToolbarAnimator.h"
26 : #endif // defined(MOZ_WIDGET_ANDROID)
27 :
28 : struct WrTransformProperty;
29 :
30 : namespace mozilla {
31 : class MultiTouchInput;
32 :
33 : namespace wr {
34 : class WebRenderAPI;
35 : }
36 :
37 : namespace layers {
38 :
39 : class Layer;
40 : class AsyncPanZoomController;
41 : class APZCTreeManagerParent;
42 : class CompositorBridgeParent;
43 : class OverscrollHandoffChain;
44 : struct OverscrollHandoffState;
45 : class FocusTarget;
46 : struct FlingHandoffState;
47 : struct ScrollableLayerGuidHash;
48 : class LayerMetricsWrapper;
49 : class InputQueue;
50 : class GeckoContentController;
51 : class HitTestingTreeNode;
52 : class WebRenderScrollData;
53 :
54 : /**
55 : * ****************** NOTE ON LOCK ORDERING IN APZ **************************
56 : *
57 : * There are two kinds of locks used by APZ: APZCTreeManager::mTreeLock
58 : * ("the tree lock") and AsyncPanZoomController::mMonitor ("APZC locks").
59 : *
60 : * To avoid deadlock, we impose a lock ordering between these locks, which is:
61 : *
62 : * tree lock -> APZC locks
63 : *
64 : * The interpretation of the lock ordering is that if lock A precedes lock B
65 : * in the ordering sequence, then you must NOT wait on A while holding B.
66 : *
67 : * **************************************************************************
68 : */
69 :
70 : /**
71 : * This class manages the tree of AsyncPanZoomController instances. There is one
72 : * instance of this class owned by each CompositorBridgeParent, and it contains as
73 : * many AsyncPanZoomController instances as there are scrollable container layers.
74 : * This class generally lives on the compositor thread, although some functions
75 : * may be called from other threads as noted; thread safety is ensured internally.
76 : *
77 : * The bulk of the work of this class happens as part of the UpdateHitTestingTree
78 : * function, which is when a layer tree update is received by the compositor.
79 : * This function walks through the layer tree and creates a tree of
80 : * HitTestingTreeNode instances to match the layer tree and for use in
81 : * hit-testing on the controller thread. APZC instances may be preserved across
82 : * calls to this function if the corresponding layers are still present in the layer
83 : * tree.
84 : *
85 : * The other functions on this class are used by various pieces of client code to
86 : * notify the APZC instances of events relevant to them. This includes, for example,
87 : * user input events that drive panning and zooming, changes to the scroll viewport
88 : * area, and changes to pan/zoom constraints.
89 : *
90 : * Note that the ClearTree function MUST be called when this class is no longer needed;
91 : * see the method documentation for details.
92 : *
93 : * Behaviour of APZ is controlled by a number of preferences shown \ref APZCPrefs "here".
94 : */
95 : class APZCTreeManager : public IAPZCTreeManager {
96 :
97 : typedef mozilla::layers::AllowedTouchBehavior AllowedTouchBehavior;
98 : typedef mozilla::layers::AsyncDragMetrics AsyncDragMetrics;
99 :
100 : // Helper struct to hold some state while we build the hit-testing tree. The
101 : // sole purpose of this struct is to shorten the argument list to
102 : // UpdateHitTestingTree. All the state that we don't need to
103 : // push on the stack during recursion and pop on unwind is stored here.
104 : struct TreeBuildingState;
105 :
106 : public:
107 : APZCTreeManager();
108 :
109 : /**
110 : * Initializes the global state used in AsyncPanZoomController.
111 : * This is normally called when it is first needed in the constructor
112 : * of APZCTreeManager, but can be called manually to force it to be
113 : * initialized earlier.
114 : */
115 : static void InitializeGlobalState();
116 :
117 : /**
118 : * Rebuild the focus state based on the focus target from the layer tree update
119 : * that just occurred.
120 : *
121 : * @param aRootLayerTreeId The layer tree ID of the root layer corresponding
122 : * to this APZCTreeManager
123 : * @param aOriginatingLayersId The layer tree ID of the layer corresponding to
124 : * this layer tree update.
125 : */
126 : void UpdateFocusState(uint64_t aRootLayerTreeId,
127 : uint64_t aOriginatingLayersId,
128 : const FocusTarget& aFocusTarget);
129 :
130 : /**
131 : * Rebuild the hit-testing tree based on the layer update that just came up.
132 : * Preserve nodes and APZC instances where possible, but retire those whose
133 : * layers are no longer in the layer tree.
134 : *
135 : * This must be called on the compositor thread as it walks the layer tree.
136 : *
137 : * @param aRootLayerTreeId The layer tree ID of the root layer corresponding
138 : * to this APZCTreeManager
139 : * @param aRoot The root of the (full) layer tree
140 : * @param aFirstPaintLayersId The layers id of the subtree to which aIsFirstPaint
141 : * applies.
142 : * @param aIsFirstPaint True if the layers update that this is called in response
143 : * to included a first-paint. If this is true, the part of
144 : * the tree that is affected by the first-paint flag is
145 : * indicated by the aFirstPaintLayersId parameter.
146 : * @param aPaintSequenceNumber The sequence number of the paint that triggered
147 : * this layer update. Note that every layer child
148 : * process' layer subtree has its own sequence
149 : * numbers.
150 : */
151 : void UpdateHitTestingTree(uint64_t aRootLayerTreeId,
152 : Layer* aRoot,
153 : bool aIsFirstPaint,
154 : uint64_t aOriginatingLayersId,
155 : uint32_t aPaintSequenceNumber);
156 :
157 : /**
158 : * Same as the above UpdateHitTestingTree, except slightly modified to take
159 : * the scrolling data passed over PWebRenderBridge instead of the raw layer
160 : * tree. This version is used when WebRender is enabled because we don't have
161 : * shadow layers in that scenario.
162 : */
163 : void UpdateHitTestingTree(uint64_t aRootLayerTreeId,
164 : const WebRenderScrollData& aScrollData,
165 : bool aIsFirstPaint,
166 : uint64_t aOriginatingLayersId,
167 : uint32_t aPaintSequenceNumber);
168 :
169 : /**
170 : * Called when webrender is enabled, from the compositor thread. This function
171 : * walks through the tree of APZC instances and tells webrender about the
172 : * async scroll position. It also advances APZ animations to the specified
173 : * sample time. In effect it is the webrender equivalent of (part of) the
174 : * code in AsyncCompositionManager. If scrollbar transforms need updating
175 : * to reflect the async scroll position, the updated transforms are appended
176 : * to the provided aTransformArray.
177 : * Returns true if any APZ animations are in progress and we need to keep
178 : * compositing.
179 : */
180 : bool PushStateToWR(wr::WebRenderAPI* aWrApi,
181 : const TimeStamp& aSampleTime,
182 : nsTArray<WrTransformProperty>& aTransformArray);
183 :
184 : /**
185 : * Walk the tree of APZCs and flushes the repaint requests for all the APZCS
186 : * corresponding to the given layers id. Finally, sends a flush complete
187 : * notification to the GeckoContentController for the layers id.
188 : */
189 : void FlushApzRepaints(uint64_t aLayersId);
190 :
191 : /**
192 : * General handler for incoming input events. Manipulates the frame metrics
193 : * based on what type of input it is. For example, a PinchGestureEvent will
194 : * cause scaling. This should only be called externally to this class, and
195 : * must be called on the controller thread.
196 : *
197 : * This function transforms |aEvent| to have its coordinates in DOM space.
198 : * This is so that the event can be passed through the DOM and content can
199 : * handle them. The event may need to be converted to a WidgetInputEvent
200 : * by the caller if it wants to do this.
201 : *
202 : * The following values may be returned by this function:
203 : * nsEventStatus_eConsumeNoDefault is returned to indicate the
204 : * APZ is consuming this event and the caller should discard the event with
205 : * extreme prejudice. The exact scenarios under which this is returned is
206 : * implementation-dependent and may vary.
207 : * nsEventStatus_eIgnore is returned to indicate that the APZ code didn't
208 : * use this event. This might be because it was directed at a point on
209 : * the screen where there was no APZ, or because the thing the user was
210 : * trying to do was not allowed. (For example, attempting to pan a
211 : * non-pannable document).
212 : * nsEventStatus_eConsumeDoDefault is returned to indicate that the APZ
213 : * code may have used this event to do some user-visible thing. Note that
214 : * in some cases CONSUMED is returned even if the event was NOT used. This
215 : * is because we cannot always know at the time of event delivery whether
216 : * the event will be used or not. So we err on the side of sending
217 : * CONSUMED when we are uncertain.
218 : *
219 : * @param aEvent input event object; is modified in-place
220 : * @param aOutTargetGuid returns the guid of the apzc this event was
221 : * delivered to. May be null.
222 : * @param aOutInputBlockId returns the id of the input block that this event
223 : * was added to, if that was the case. May be null.
224 : */
225 : nsEventStatus ReceiveInputEvent(
226 : InputData& aEvent,
227 : ScrollableLayerGuid* aOutTargetGuid,
228 : uint64_t* aOutInputBlockId) override;
229 :
230 : /**
231 : * Set the keyboard shortcuts to use for translating keyboard events.
232 : */
233 : void SetKeyboardMap(const KeyboardMap& aKeyboardMap) override;
234 :
235 : /**
236 : * Kicks an animation to zoom to a rect. This may be either a zoom out or zoom
237 : * in. The actual animation is done on the compositor thread after being set
238 : * up. |aRect| must be given in CSS pixels, relative to the document.
239 : * |aFlags| is a combination of the ZoomToRectBehavior enum values.
240 : */
241 : void ZoomToRect(
242 : const ScrollableLayerGuid& aGuid,
243 : const CSSRect& aRect,
244 : const uint32_t aFlags = DEFAULT_BEHAVIOR) override;
245 :
246 : /**
247 : * If we have touch listeners, this should always be called when we know
248 : * definitively whether or not content has preventDefaulted any touch events
249 : * that have come in. If |aPreventDefault| is true, any touch events in the
250 : * queue will be discarded. This function must be called on the controller
251 : * thread.
252 : */
253 : void ContentReceivedInputBlock(
254 : uint64_t aInputBlockId,
255 : bool aPreventDefault) override;
256 :
257 : /**
258 : * When the event regions code is enabled, this function should be invoked to
259 : * to confirm the target of the input block. This is only needed in cases
260 : * where the initial input event of the block hit a dispatch-to-content region
261 : * but is safe to call for all input blocks. This function should always be
262 : * invoked on the controller thread.
263 : * The different elements in the array of targets correspond to the targets
264 : * for the different touch points. In the case where the touch point has no
265 : * target, or the target is not a scrollable frame, the target's |mScrollId|
266 : * should be set to FrameMetrics::NULL_SCROLL_ID.
267 : */
268 : void SetTargetAPZC(
269 : uint64_t aInputBlockId,
270 : const nsTArray<ScrollableLayerGuid>& aTargets) override;
271 :
272 : /**
273 : * Helper function for SetTargetAPZC when used with single-target events,
274 : * such as mouse wheel events.
275 : */
276 : void SetTargetAPZC(uint64_t aInputBlockId, const ScrollableLayerGuid& aTarget);
277 :
278 : /**
279 : * Updates any zoom constraints contained in the <meta name="viewport"> tag.
280 : * If the |aConstraints| is Nothing() then previously-provided constraints for
281 : * the given |aGuid| are cleared.
282 : */
283 : void UpdateZoomConstraints(
284 : const ScrollableLayerGuid& aGuid,
285 : const Maybe<ZoomConstraints>& aConstraints) override;
286 :
287 : /**
288 : * Cancels any currently running animation. Note that all this does is set the
289 : * state of the AsyncPanZoomController back to NOTHING, but it is the
290 : * animation's responsibility to check this before advancing.
291 : */
292 : void CancelAnimation(const ScrollableLayerGuid &aGuid) override;
293 :
294 : /**
295 : * Adjusts the root APZC to compensate for a shift in the surface. See the
296 : * documentation on AsyncPanZoomController::AdjustScrollForSurfaceShift for
297 : * some more details. This is only currently needed due to surface shifts
298 : * caused by the dynamic toolbar on Android.
299 : */
300 : void AdjustScrollForSurfaceShift(const ScreenPoint& aShift);
301 :
302 : /**
303 : * Calls Destroy() on all APZC instances attached to the tree, and resets the
304 : * tree back to empty. This function must be called exactly once during the
305 : * lifetime of this APZCTreeManager, when this APZCTreeManager is no longer
306 : * needed. Failing to call this function may prevent objects from being freed
307 : * properly.
308 : */
309 : void ClearTree();
310 :
311 : /**
312 : * Tests if a screen point intersect an apz in the tree.
313 : */
314 : bool HitTestAPZC(const ScreenIntPoint& aPoint);
315 :
316 : /**
317 : * See AsyncPanZoomController::CalculatePendingDisplayPort. This
318 : * function simply delegates to that one, so that non-layers code
319 : * never needs to include AsyncPanZoomController.h
320 : */
321 : static const ScreenMargin CalculatePendingDisplayPort(
322 : const FrameMetrics& aFrameMetrics,
323 : const ParentLayerPoint& aVelocity);
324 :
325 : /**
326 : * Sets the dpi value used by all AsyncPanZoomControllers.
327 : * DPI defaults to 72 if not set using SetDPI() at any point.
328 : */
329 1 : void SetDPI(float aDpiValue) override { sDPI = aDpiValue; }
330 :
331 : /**
332 : * Returns the current dpi value in use.
333 : */
334 0 : static float GetDPI() { return sDPI; }
335 :
336 : /**
337 : * Find the hit testing node for the scrollbar thumb that matches these
338 : * drag metrics.
339 : */
340 : RefPtr<HitTestingTreeNode> FindScrollThumbNode(const AsyncDragMetrics& aDragMetrics);
341 :
342 : /**
343 : * Sets allowed touch behavior values for current touch-session for specific
344 : * input block (determined by aInputBlock).
345 : * Should be invoked by the widget. Each value of the aValues arrays
346 : * corresponds to the different touch point that is currently active.
347 : * Must be called after receiving the TOUCH_START event that starts the
348 : * touch-session.
349 : * This must be called on the controller thread.
350 : */
351 : void SetAllowedTouchBehavior(
352 : uint64_t aInputBlockId,
353 : const nsTArray<TouchBehaviorFlags>& aValues) override;
354 :
355 : /**
356 : * This is a callback for AsyncPanZoomController to call when it wants to
357 : * scroll in response to a touch-move event, or when it needs to hand off
358 : * overscroll to the next APZC. Note that because of scroll grabbing, the
359 : * first APZC to scroll may not be the one that is receiving the touch events.
360 : *
361 : * |aAPZC| is the APZC that received the touch events triggering the scroll
362 : * (in the case of an initial scroll), or the last APZC to scroll (in the
363 : * case of overscroll)
364 : * |aStartPoint| and |aEndPoint| are in |aAPZC|'s transformed screen
365 : * coordinates (i.e. the same coordinates in which touch points are given to
366 : * APZCs). The amount of (over)scroll is represented by two points rather
367 : * than a displacement because with certain 3D transforms, the same
368 : * displacement between different points in transformed coordinates can
369 : * represent different displacements in untransformed coordinates.
370 : * |aOverscrollHandoffChain| is the overscroll handoff chain used for
371 : * determining the order in which scroll should be handed off between
372 : * APZCs
373 : * |aOverscrollHandoffChainIndex| is the next position in the overscroll
374 : * handoff chain that should be scrolled.
375 : *
376 : * aStartPoint and aEndPoint will be modified depending on how much of the
377 : * scroll each APZC consumes. This is to allow the sending APZC to go into
378 : * an overscrolled state if no APZC further up in the handoff chain accepted
379 : * the entire scroll.
380 : *
381 : * The way this method works is best illustrated with an example.
382 : * Consider three nested APZCs, A, B, and C, with C being the innermost one.
383 : * Say B is scroll-grabbing.
384 : * The touch events go to C because it's the innermost one (so e.g. taps
385 : * should go through C), but the overscroll handoff chain is B -> C -> A
386 : * because B is scroll-grabbing.
387 : * For convenience I'll refer to the three APZC objects as A, B, and C, and
388 : * to the tree manager object as TM.
389 : * Here's what happens when C receives a touch-move event:
390 : * - C.TrackTouch() calls TM.DispatchScroll() with index = 0.
391 : * - TM.DispatchScroll() calls B.AttemptScroll() (since B is at index 0 in the chain).
392 : * - B.AttemptScroll() scrolls B. If there is overscroll, it calls TM.DispatchScroll() with index = 1.
393 : * - TM.DispatchScroll() calls C.AttemptScroll() (since C is at index 1 in the chain)
394 : * - C.AttemptScroll() scrolls C. If there is overscroll, it calls TM.DispatchScroll() with index = 2.
395 : * - TM.DispatchScroll() calls A.AttemptScroll() (since A is at index 2 in the chain)
396 : * - A.AttemptScroll() scrolls A. If there is overscroll, it calls TM.DispatchScroll() with index = 3.
397 : * - TM.DispatchScroll() discards the rest of the scroll as there are no more elements in the chain.
398 : *
399 : * Note: this should be used for panning only. For handing off overscroll for
400 : * a fling, use DispatchFling().
401 : */
402 : void DispatchScroll(AsyncPanZoomController* aApzc,
403 : ParentLayerPoint& aStartPoint,
404 : ParentLayerPoint& aEndPoint,
405 : OverscrollHandoffState& aOverscrollHandoffState);
406 :
407 : /**
408 : * This is a callback for AsyncPanZoomController to call when it wants to
409 : * start a fling in response to a touch-end event, or when it needs to hand
410 : * off a fling to the next APZC. Note that because of scroll grabbing, the
411 : * first APZC to fling may not be the one that is receiving the touch events.
412 : *
413 : * @param aApzc the APZC that wants to start or hand off the fling
414 : * @param aHandoffState a collection of state about the operation,
415 : * which contains the following:
416 : *
417 : * mVelocity the current velocity of the fling, in |aApzc|'s screen
418 : * pixels per millisecond
419 : * mChain the chain of APZCs along which the fling
420 : * should be handed off
421 : * mIsHandoff is true if |aApzc| is handing off an existing fling (in
422 : * this case the fling is given to the next APZC in the
423 : * handoff chain after |aApzc|), and false is |aApzc| wants
424 : * start a fling (in this case the fling is given to the
425 : * first APZC in the chain)
426 : *
427 : * aHandoffState.mVelocity will be modified depending on how much of that
428 : * velocity has been consumed by APZCs in the overscroll hand-off chain.
429 : * The caller can use this value to determine whether it should consume
430 : * the excess velocity by going into an overscroll fling.
431 : */
432 : void DispatchFling(AsyncPanZoomController* aApzc,
433 : FlingHandoffState& aHandoffState);
434 :
435 : void StartScrollbarDrag(
436 : const ScrollableLayerGuid& aGuid,
437 : const AsyncDragMetrics& aDragMetrics) override;
438 :
439 : /*
440 : * Build the chain of APZCs that will handle overscroll for a pan starting at |aInitialTarget|.
441 : */
442 : RefPtr<const OverscrollHandoffChain> BuildOverscrollHandoffChain(const RefPtr<AsyncPanZoomController>& aInitialTarget);
443 :
444 : /**
445 : * Function used to disable LongTap gestures.
446 : *
447 : * On slow running tests, drags and touch events can be misinterpreted
448 : * as a long tap. This allows tests to disable long tap gesture detection.
449 : */
450 : void SetLongTapEnabled(bool aTapGestureEnabled) override;
451 :
452 : // Methods to help process WidgetInputEvents (or manage conversion to/from InputData)
453 :
454 : void ProcessUnhandledEvent(
455 : LayoutDeviceIntPoint* aRefPoint,
456 : ScrollableLayerGuid* aOutTargetGuid,
457 : uint64_t* aOutFocusSequenceNumber) override;
458 :
459 : void UpdateWheelTransaction(
460 : LayoutDeviceIntPoint aRefPoint,
461 : EventMessage aEventMessage) override;
462 :
463 : protected:
464 : // Protected destructor, to discourage deletion outside of Release():
465 : virtual ~APZCTreeManager();
466 :
467 : // Protected hooks for gtests subclass
468 : virtual AsyncPanZoomController* NewAPZCInstance(uint64_t aLayersId,
469 : GeckoContentController* aController);
470 : public:
471 : // Public hooks for gtests subclass
472 : virtual TimeStamp GetFrameTime();
473 :
474 : public:
475 : /* Some helper functions to find an APZC given some identifying input. These functions
476 : lock the tree of APZCs while they find the right one, and then return an addref'd
477 : pointer to it. This allows caller code to just use the target APZC without worrying
478 : about it going away. These are public for testing code and generally should not be
479 : used by other production code.
480 : */
481 : RefPtr<HitTestingTreeNode> GetRootNode() const;
482 : already_AddRefed<AsyncPanZoomController> GetTargetAPZC(const ScreenPoint& aPoint,
483 : HitTestResult* aOutHitResult,
484 : HitTestingTreeNode** aOutScrollbarNode = nullptr);
485 : already_AddRefed<AsyncPanZoomController> GetTargetAPZC(const uint64_t& aLayersId,
486 : const FrameMetrics::ViewID& aScrollId);
487 : ScreenToParentLayerMatrix4x4 GetScreenToApzcTransform(const AsyncPanZoomController *aApzc) const;
488 : ParentLayerToScreenMatrix4x4 GetApzcToGeckoTransform(const AsyncPanZoomController *aApzc) const;
489 :
490 : /**
491 : * Process touch velocity.
492 : * Sometimes the touch move event will have a velocity even though no scrolling
493 : * is occurring such as when the toolbar is being hidden/shown in Fennec.
494 : * This function can be called to have the y axis' velocity queue updated.
495 : */
496 : void ProcessTouchVelocity(uint32_t aTimestampMs, float aSpeedY) override;
497 : private:
498 : typedef bool (*GuidComparator)(const ScrollableLayerGuid&, const ScrollableLayerGuid&);
499 :
500 : /* Helpers */
501 : template<class ScrollNode>
502 : void UpdateHitTestingTreeImpl(uint64_t aRootLayerTreeId,
503 : const ScrollNode& aRoot,
504 : bool aIsFirstPaint,
505 : uint64_t aOriginatingLayersId,
506 : uint32_t aPaintSequenceNumber);
507 :
508 : void AttachNodeToTree(HitTestingTreeNode* aNode,
509 : HitTestingTreeNode* aParent,
510 : HitTestingTreeNode* aNextSibling);
511 : already_AddRefed<AsyncPanZoomController> GetTargetAPZC(const ScrollableLayerGuid& aGuid);
512 : already_AddRefed<HitTestingTreeNode> GetTargetNode(const ScrollableLayerGuid& aGuid,
513 : GuidComparator aComparator) const;
514 : HitTestingTreeNode* FindTargetNode(HitTestingTreeNode* aNode,
515 : const ScrollableLayerGuid& aGuid,
516 : GuidComparator aComparator);
517 : AsyncPanZoomController* GetTargetApzcForNode(HitTestingTreeNode* aNode);
518 : AsyncPanZoomController* GetAPZCAtPoint(HitTestingTreeNode* aNode,
519 : const ParentLayerPoint& aHitTestPoint,
520 : HitTestResult* aOutHitResult,
521 : HitTestingTreeNode** aOutScrollbarNode);
522 : AsyncPanZoomController* FindRootApzcForLayersId(uint64_t aLayersId) const;
523 : AsyncPanZoomController* FindRootContentApzcForLayersId(uint64_t aLayersId) const;
524 : AsyncPanZoomController* FindRootContentOrRootApzc() const;
525 : already_AddRefed<AsyncPanZoomController> GetMultitouchTarget(AsyncPanZoomController* aApzc1, AsyncPanZoomController* aApzc2) const;
526 : already_AddRefed<AsyncPanZoomController> CommonAncestor(AsyncPanZoomController* aApzc1, AsyncPanZoomController* aApzc2) const;
527 : already_AddRefed<AsyncPanZoomController> GetTouchInputBlockAPZC(const MultiTouchInput& aEvent,
528 : nsTArray<TouchBehaviorFlags>* aOutTouchBehaviors,
529 : HitTestResult* aOutHitResult);
530 : nsEventStatus ProcessTouchInput(MultiTouchInput& aInput,
531 : ScrollableLayerGuid* aOutTargetGuid,
532 : uint64_t* aOutInputBlockId);
533 : void FlushRepaintsToClearScreenToGeckoTransform();
534 :
535 : already_AddRefed<HitTestingTreeNode> RecycleOrCreateNode(TreeBuildingState& aState,
536 : AsyncPanZoomController* aApzc,
537 : uint64_t aLayersId);
538 : template<class ScrollNode>
539 : HitTestingTreeNode* PrepareNodeForLayer(const ScrollNode& aLayer,
540 : const FrameMetrics& aMetrics,
541 : uint64_t aLayersId,
542 : const gfx::Matrix4x4& aAncestorTransform,
543 : HitTestingTreeNode* aParent,
544 : HitTestingTreeNode* aNextSibling,
545 : TreeBuildingState& aState);
546 :
547 : template<class ScrollNode>
548 : void PrintAPZCInfo(const ScrollNode& aLayer,
549 : const AsyncPanZoomController* apzc);
550 :
551 : void NotifyScrollbarDragRejected(const ScrollableLayerGuid& aGuid) const;
552 :
553 : // Requires the caller to hold mTreeLock.
554 : LayerToParentLayerMatrix4x4 ComputeTransformForNode(const HitTestingTreeNode* aNode) const;
555 :
556 : protected:
557 : /* The input queue where input events are held until we know enough to
558 : * figure out where they're going. Protected so gtests can access it.
559 : */
560 : RefPtr<InputQueue> mInputQueue;
561 :
562 : private:
563 : /* Whenever walking or mutating the tree rooted at mRootNode, mTreeLock must be held.
564 : * This lock does not need to be held while manipulating a single APZC instance in
565 : * isolation (that is, if its tree pointers are not being accessed or mutated). The
566 : * lock also needs to be held when accessing the mRootNode instance variable, as that
567 : * is considered part of the APZC tree management state.
568 : * Finally, the lock needs to be held when accessing mZoomConstraints.
569 : * IMPORTANT: See the note about lock ordering at the top of this file. */
570 : mutable mozilla::Mutex mTreeLock;
571 : RefPtr<HitTestingTreeNode> mRootNode;
572 : /* Holds the zoom constraints for scrollable layers, as determined by the
573 : * the main-thread gecko code. */
574 : std::unordered_map<ScrollableLayerGuid, ZoomConstraints, ScrollableLayerGuidHash> mZoomConstraints;
575 : /* A list of keyboard shortcuts to use for translating keyboard inputs into
576 : * keyboard actions. This is gathered on the main thread from XBL bindings.
577 : */
578 : KeyboardMap mKeyboardMap;
579 : /* This tracks the focus targets of chrome and content and whether we have
580 : * a current focus target or whether we are waiting for a new confirmation.
581 : */
582 : FocusState mFocusState;
583 : /* This tracks the APZC that should receive all inputs for the current input event block.
584 : * This allows touch points to move outside the thing they started on, but still have the
585 : * touch events delivered to the same initial APZC. This will only ever be touched on the
586 : * input delivery thread, and so does not require locking.
587 : */
588 : RefPtr<AsyncPanZoomController> mApzcForInputBlock;
589 : /* The hit result for the current input event block; this should always be in
590 : * sync with mApzcForInputBlock.
591 : */
592 : HitTestResult mHitResultForInputBlock;
593 : /* Sometimes we want to ignore all touches except one. In such cases, this
594 : * is set to the identifier of the touch we are not ignoring; in other cases,
595 : * this is set to -1.
596 : */
597 : int32_t mRetainedTouchIdentifier;
598 : /* Tracks the number of touch points we are tracking that are currently on
599 : * the screen. */
600 : TouchCounter mTouchCounter;
601 : /* For logging the APZC tree for debugging (enabled by the apz.printtree
602 : * pref). */
603 : gfx::TreeLog mApzcTreeLog;
604 :
605 : class CheckerboardFlushObserver;
606 : friend class CheckerboardFlushObserver;
607 : RefPtr<CheckerboardFlushObserver> mFlushObserver;
608 :
609 : static float sDPI;
610 :
611 : #if defined(MOZ_WIDGET_ANDROID)
612 : public:
613 : void InitializeDynamicToolbarAnimator(const int64_t& aRootLayerTreeId);
614 : AndroidDynamicToolbarAnimator* GetAndroidDynamicToolbarAnimator();
615 :
616 : private:
617 : RefPtr<AndroidDynamicToolbarAnimator> mToolbarAnimator;
618 : #endif // defined(MOZ_WIDGET_ANDROID)
619 : };
620 :
621 : } // namespace layers
622 : } // namespace mozilla
623 :
624 : #endif // mozilla_layers_PanZoomController_h
|