Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim: set sw=2 ts=8 et tw=80 : */
3 : /* This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this
5 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : #ifndef mozilla_layers_AsyncPanZoomController_h
8 : #define mozilla_layers_AsyncPanZoomController_h
9 :
10 : #include "CrossProcessMutex.h"
11 : #include "mozilla/layers/GeckoContentController.h"
12 : #include "mozilla/layers/APZCTreeManager.h"
13 : #include "mozilla/layers/AsyncPanZoomAnimation.h"
14 : #include "mozilla/Attributes.h"
15 : #include "mozilla/EventForwards.h"
16 : #include "mozilla/Monitor.h"
17 : #include "mozilla/ReentrantMonitor.h"
18 : #include "mozilla/RefPtr.h"
19 : #include "mozilla/UniquePtr.h"
20 : #include "mozilla/Atomics.h"
21 : #include "InputData.h"
22 : #include "Axis.h"
23 : #include "InputQueue.h"
24 : #include "APZUtils.h"
25 : #include "Layers.h" // for Layer::ScrollDirection
26 : #include "LayersTypes.h"
27 : #include "mozilla/gfx/Matrix.h"
28 : #include "nsIScrollableFrame.h"
29 : #include "nsRegion.h"
30 : #include "nsTArray.h"
31 : #include "PotentialCheckerboardDurationTracker.h"
32 :
33 : #include "base/message_loop.h"
34 :
35 : namespace mozilla {
36 :
37 : namespace ipc {
38 :
39 : class SharedMemoryBasic;
40 :
41 : } // namespace ipc
42 :
43 : namespace layers {
44 :
45 : class AsyncDragMetrics;
46 : struct ScrollableLayerGuid;
47 : class CompositorController;
48 : class MetricsSharingController;
49 : class GestureEventListener;
50 : struct AsyncTransform;
51 : class AsyncPanZoomAnimation;
52 : class AndroidFlingAnimation;
53 : class GenericFlingAnimation;
54 : class InputBlockState;
55 : class TouchBlockState;
56 : class PanGestureBlockState;
57 : class OverscrollHandoffChain;
58 : class StateChangeNotificationBlocker;
59 : class CheckerboardEvent;
60 : class OverscrollEffectBase;
61 : class WidgetOverscrollEffect;
62 : class GenericOverscrollEffect;
63 : class AndroidSpecificState;
64 : struct KeyboardScrollAction;
65 :
66 : // Base class for grouping platform-specific APZC state variables.
67 0 : class PlatformSpecificStateBase {
68 : public:
69 0 : virtual ~PlatformSpecificStateBase() {}
70 0 : virtual AndroidSpecificState* AsAndroidSpecificState() { return nullptr; }
71 : };
72 :
73 : /**
74 : * Controller for all panning and zooming logic. Any time a user input is
75 : * detected and it must be processed in some way to affect what the user sees,
76 : * it goes through here. Listens for any input event from InputData and can
77 : * optionally handle WidgetGUIEvent-derived touch events, but this must be done
78 : * on the main thread. Note that this class completely cross-platform.
79 : *
80 : * Input events originate on the UI thread of the platform that this runs on,
81 : * and are then sent to this class. This class processes the event in some way;
82 : * for example, a touch move will usually lead to a panning of content (though
83 : * of course there are exceptions, such as if content preventDefaults the event,
84 : * or if the target frame is not scrollable). The compositor interacts with this
85 : * class by locking it and querying it for the current transform matrix based on
86 : * the panning and zooming logic that was invoked on the UI thread.
87 : *
88 : * Currently, each outer DOM window (i.e. a website in a tab, but not any
89 : * subframes) has its own AsyncPanZoomController. In the future, to support
90 : * asynchronously scrolled subframes, we want to have one AsyncPanZoomController
91 : * per frame.
92 : */
93 : class AsyncPanZoomController {
94 114 : NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AsyncPanZoomController)
95 :
96 : typedef mozilla::MonitorAutoLock MonitorAutoLock;
97 : typedef mozilla::gfx::Matrix4x4 Matrix4x4;
98 :
99 : public:
100 : enum GestureBehavior {
101 : // The platform code is responsible for forwarding gesture events here. We
102 : // will not attempt to generate gesture events from MultiTouchInputs.
103 : DEFAULT_GESTURES,
104 : // An instance of GestureEventListener is used to detect gestures. This is
105 : // handled completely internally within this class.
106 : USE_GESTURE_DETECTOR
107 : };
108 :
109 : /**
110 : * Constant describing the tolerance in distance we use, multiplied by the
111 : * device DPI, before we start panning the screen. This is to prevent us from
112 : * accidentally processing taps as touch moves, and from very short/accidental
113 : * touches moving the screen.
114 : * Note: It's an abuse of the 'Coord' class to use it to represent a 2D
115 : * distance, but it's the closest thing we currently have.
116 : */
117 : static ScreenCoord GetTouchStartTolerance();
118 :
119 : AsyncPanZoomController(uint64_t aLayersId,
120 : APZCTreeManager* aTreeManager,
121 : const RefPtr<InputQueue>& aInputQueue,
122 : GeckoContentController* aController,
123 : GestureBehavior aGestures = DEFAULT_GESTURES);
124 :
125 : // --------------------------------------------------------------------------
126 : // These methods must only be called on the gecko thread.
127 : //
128 :
129 : /**
130 : * Read the various prefs and do any global initialization for all APZC instances.
131 : * This must be run on the gecko thread before any APZC instances are actually
132 : * used for anything meaningful.
133 : */
134 : static void InitializeGlobalState();
135 :
136 : // --------------------------------------------------------------------------
137 : // These methods must only be called on the controller/UI thread.
138 : //
139 :
140 : /**
141 : * Kicks an animation to zoom to a rect. This may be either a zoom out or zoom
142 : * in. The actual animation is done on the compositor thread after being set
143 : * up.
144 : */
145 : void ZoomToRect(CSSRect aRect, const uint32_t aFlags);
146 :
147 : /**
148 : * Updates any zoom constraints contained in the <meta name="viewport"> tag.
149 : */
150 : void UpdateZoomConstraints(const ZoomConstraints& aConstraints);
151 :
152 : /**
153 : * Return the zoom constraints last set for this APZC (in the constructor
154 : * or in UpdateZoomConstraints()).
155 : */
156 : ZoomConstraints GetZoomConstraints() const;
157 :
158 : /**
159 : * Schedules a runnable to run on the controller/UI thread at some time
160 : * in the future.
161 : */
162 : void PostDelayedTask(already_AddRefed<Runnable> aTask, int aDelayMs);
163 :
164 : // --------------------------------------------------------------------------
165 : // These methods must only be called on the compositor thread.
166 : //
167 :
168 : /**
169 : * Advances any animations currently running to the given timestamp.
170 : * This may be called multiple times with the same timestamp.
171 : *
172 : * The return value indicates whether or not any currently running animation
173 : * should continue. If true, the compositor should schedule another composite.
174 : */
175 : bool AdvanceAnimations(const TimeStamp& aSampleTime);
176 :
177 : bool UpdateAnimation(const TimeStamp& aSampleTime,
178 : nsTArray<RefPtr<Runnable>>* aOutDeferredTasks);
179 :
180 : /**
181 : * A shadow layer update has arrived. |aScrollMetdata| is the new ScrollMetadata
182 : * for the container layer corresponding to this APZC.
183 : * |aIsFirstPaint| is a flag passed from the shadow
184 : * layers code indicating that the scroll metadata being sent with this call are
185 : * the initial metadata and the initial paint of the frame has just happened.
186 : */
187 : void NotifyLayersUpdated(const ScrollMetadata& aScrollMetadata, bool aIsFirstPaint,
188 : bool aThisLayerTreeUpdated);
189 :
190 : /**
191 : * The platform implementation must set the compositor controller so that we can
192 : * request composites.
193 : */
194 : void SetCompositorController(CompositorController* aCompositorController);
195 :
196 : /**
197 : * If we need to share the frame metrics with some other thread, this controller
198 : * needs to be set and provides relevant information/APIs.
199 : */
200 : void SetMetricsSharingController(MetricsSharingController* aMetricsSharingController);
201 :
202 : // --------------------------------------------------------------------------
203 : // These methods can be called from any thread.
204 : //
205 :
206 : /**
207 : * Shut down the controller/UI thread state and prepare to be
208 : * deleted (which may happen from any thread).
209 : */
210 : void Destroy();
211 :
212 : /**
213 : * Returns true if Destroy() has already been called on this APZC instance.
214 : */
215 : bool IsDestroyed() const;
216 :
217 : /**
218 : * Returns the transform to take something from the coordinate space of the
219 : * last thing we know gecko painted, to the coordinate space of the last thing
220 : * we asked gecko to paint. In cases where that last request has not yet been
221 : * processed, this is needed to transform input events properly into a space
222 : * gecko will understand.
223 : */
224 : Matrix4x4 GetTransformToLastDispatchedPaint() const;
225 :
226 : /**
227 : * Returns the number of CSS pixels of checkerboard according to the metrics
228 : * in this APZC.
229 : */
230 : uint32_t GetCheckerboardMagnitude() const;
231 :
232 : /**
233 : * Report the number of CSSPixel-milliseconds of checkerboard to telemetry.
234 : */
235 : void ReportCheckerboard(const TimeStamp& aSampleTime);
236 :
237 : /**
238 : * Flush any active checkerboard report that's in progress. This basically
239 : * pretends like any in-progress checkerboard event has terminated, and pushes
240 : * out the report to the checkerboard reporting service and telemetry. If the
241 : * checkerboard event has not really finished, it will start a new event
242 : * on the next composite.
243 : */
244 : void FlushActiveCheckerboardReport();
245 :
246 : /**
247 : * Returns whether or not the APZC is currently in a state of checkerboarding.
248 : * This is a simple computation based on the last-painted content and whether
249 : * the async transform has pushed it so far that it doesn't fully contain the
250 : * composition bounds.
251 : */
252 : bool IsCurrentlyCheckerboarding() const;
253 :
254 : /**
255 : * Recalculates the displayport. Ideally, this should paint an area bigger
256 : * than the composite-to dimensions so that when you scroll down, you don't
257 : * checkerboard immediately. This includes a bunch of logic, including
258 : * algorithms to bias painting in the direction of the velocity.
259 : */
260 : static const ScreenMargin CalculatePendingDisplayPort(
261 : const FrameMetrics& aFrameMetrics,
262 : const ParentLayerPoint& aVelocity);
263 :
264 : nsEventStatus HandleDragEvent(const MouseInput& aEvent,
265 : const AsyncDragMetrics& aDragMetrics,
266 : CSSCoord aInitialThumbPos);
267 :
268 : /**
269 : * Handler for events which should not be intercepted by the touch listener.
270 : */
271 : nsEventStatus HandleInputEvent(const InputData& aEvent,
272 : const ScreenToParentLayerMatrix4x4& aTransformToApzc);
273 :
274 : /**
275 : * Handler for gesture events.
276 : * Currently some gestures are detected in GestureEventListener that calls
277 : * APZC back through this handler in order to avoid recursive calls to
278 : * APZC::HandleInputEvent() which is supposed to do the work for
279 : * ReceiveInputEvent().
280 : */
281 : nsEventStatus HandleGestureEvent(const InputData& aEvent);
282 :
283 : /**
284 : * Handler for touch velocity.
285 : * Sometimes the touch move event will have a velocity even though no scrolling
286 : * is occurring such as when the toolbar is being hidden/shown in Fennec.
287 : * This function can be called to have the y axis' velocity queue updated.
288 : */
289 : void HandleTouchVelocity(uint32_t aTimesampMs, float aSpeedY);
290 :
291 : /**
292 : * Populates the provided object (if non-null) with the scrollable guid of this apzc.
293 : */
294 : void GetGuid(ScrollableLayerGuid* aGuidOut) const;
295 :
296 : /**
297 : * Returns the scrollable guid of this apzc.
298 : */
299 : ScrollableLayerGuid GetGuid() const;
300 :
301 : /**
302 : * Returns true if this APZC instance is for the layer identified by the guid.
303 : */
304 : bool Matches(const ScrollableLayerGuid& aGuid);
305 :
306 : /**
307 : * Returns true if the tree manager of this APZC is the same as the one
308 : * passed in.
309 : */
310 : bool HasTreeManager(const APZCTreeManager* aTreeManager) const;
311 :
312 : void StartAnimation(AsyncPanZoomAnimation* aAnimation);
313 :
314 : /**
315 : * Cancels any currently running animation.
316 : * aFlags is a bit-field to provide specifics of how to cancel the animation.
317 : * See CancelAnimationFlags.
318 : */
319 : void CancelAnimation(CancelAnimationFlags aFlags = Default);
320 :
321 : /**
322 : * Adjusts the scroll position to compensate for a shift in the surface, such
323 : * that the content appears to remain visually in the same position. i.e. if
324 : * the surface moves up by 10 screenpixels, the scroll position should also
325 : * move up by 10 pixels so that what used to be at the top of the surface is
326 : * now 10 pixels down the surface. Will request that content be repainted
327 : * if necessary but will not request a composite. It is assumed the dynamic
328 : * toolbar animator will request the composite.
329 : */
330 : void AdjustScrollForSurfaceShift(const ScreenPoint& aShift);
331 :
332 : /**
333 : * Clear any overscroll on this APZC.
334 : */
335 : void ClearOverscroll();
336 :
337 : /**
338 : * Returns whether this APZC is for an element marked with the 'scrollgrab'
339 : * attribute.
340 : */
341 39 : bool HasScrollgrab() const { return mScrollMetadata.GetHasScrollgrab(); }
342 :
343 : /**
344 : * Returns whether this APZC has scroll snap points.
345 : */
346 : bool HasScrollSnapping() const {
347 : return mScrollMetadata.GetSnapInfo().HasScrollSnapping();
348 : }
349 :
350 : /**
351 : * Returns whether this APZC has room to be panned (in any direction).
352 : */
353 : bool IsPannable() const;
354 :
355 : /**
356 : * Returns whether this APZC represents a scroll info layer.
357 : */
358 : bool IsScrollInfoLayer() const;
359 :
360 : /**
361 : * Returns true if the APZC has been flung with a velocity greater than the
362 : * stop-on-tap fling velocity threshold (which is pref-controlled).
363 : */
364 : bool IsFlingingFast() const;
365 :
366 : /**
367 : * Returns the identifier of the touch in the last touch event processed by
368 : * this APZC. This should only be called when the last touch event contained
369 : * only one touch.
370 : */
371 : int32_t GetLastTouchIdentifier() const;
372 :
373 : /**
374 : * Returns the matrix that transforms points from global screen space into
375 : * this APZC's ParentLayer space.
376 : * To respect the lock ordering, mMonitor must NOT be held when calling
377 : * this function (since this function acquires the tree lock).
378 : */
379 : ScreenToParentLayerMatrix4x4 GetTransformToThis() const;
380 :
381 : /**
382 : * Convert the vector |aVector|, rooted at the point |aAnchor|, from
383 : * this APZC's ParentLayer coordinates into screen coordinates.
384 : * The anchor is necessary because with 3D tranforms, the location of the
385 : * vector can affect the result of the transform.
386 : * To respect the lock ordering, mMonitor must NOT be held when calling
387 : * this function (since this function acquires the tree lock).
388 : */
389 : ScreenPoint ToScreenCoordinates(const ParentLayerPoint& aVector,
390 : const ParentLayerPoint& aAnchor) const;
391 :
392 : /**
393 : * Convert the vector |aVector|, rooted at the point |aAnchor|, from
394 : * screen coordinates into this APZC's ParentLayer coordinates.
395 : * The anchor is necessary because with 3D tranforms, the location of the
396 : * vector can affect the result of the transform.
397 : * To respect the lock ordering, mMonitor must NOT be held when calling
398 : * this function (since this function acquires the tree lock).
399 : */
400 : ParentLayerPoint ToParentLayerCoordinates(const ScreenPoint& aVector,
401 : const ScreenPoint& aAnchor) const;
402 :
403 : // Return whether or not a wheel event will be able to scroll in either
404 : // direction.
405 : bool CanScroll(const InputData& aEvent) const;
406 :
407 : // Return whether or not a scroll delta will be able to scroll in either
408 : // direction.
409 : bool CanScrollWithWheel(const ParentLayerPoint& aDelta) const;
410 :
411 : // Return whether or not there is room to scroll this APZC
412 : // in the given direction.
413 : bool CanScroll(ScrollDirection aDirection) const;
414 :
415 : /**
416 : * Convert a point on the scrollbar from this APZC's ParentLayer coordinates
417 : * to CSS coordinates relative to the beginning of the scroll track.
418 : * Only the component in the direction of scrolling is returned.
419 : */
420 : CSSCoord ConvertScrollbarPoint(const ParentLayerPoint& aScrollbarPoint,
421 : const ScrollThumbData& aThumbData) const;
422 :
423 : void NotifyMozMouseScrollEvent(const nsString& aString) const;
424 :
425 : protected:
426 : // Protected destructor, to discourage deletion outside of Release():
427 : virtual ~AsyncPanZoomController();
428 :
429 : // Returns the cached current frame time.
430 : TimeStamp GetFrameTime() const;
431 :
432 : /**
433 : * Helper method for touches beginning. Sets everything up for panning and any
434 : * multitouch gestures.
435 : */
436 : nsEventStatus OnTouchStart(const MultiTouchInput& aEvent);
437 :
438 : /**
439 : * Helper method for touches moving. Does any transforms needed when panning.
440 : */
441 : nsEventStatus OnTouchMove(const MultiTouchInput& aEvent);
442 :
443 : /**
444 : * Helper method for touches ending. Redraws the screen if necessary and does
445 : * any cleanup after a touch has ended.
446 : */
447 : nsEventStatus OnTouchEnd(const MultiTouchInput& aEvent);
448 :
449 : /**
450 : * Helper method for touches being cancelled. Treated roughly the same as a
451 : * touch ending (OnTouchEnd()).
452 : */
453 : nsEventStatus OnTouchCancel(const MultiTouchInput& aEvent);
454 :
455 : /**
456 : * Helper method for scales beginning. Distinct from the OnTouch* handlers in
457 : * that this implies some outside implementation has determined that the user
458 : * is pinching.
459 : */
460 : nsEventStatus OnScaleBegin(const PinchGestureInput& aEvent);
461 :
462 : /**
463 : * Helper method for scaling. As the user moves their fingers when pinching,
464 : * this changes the scale of the page.
465 : */
466 : nsEventStatus OnScale(const PinchGestureInput& aEvent);
467 :
468 : /**
469 : * Helper method for scales ending. Redraws the screen if necessary and does
470 : * any cleanup after a scale has ended.
471 : */
472 : nsEventStatus OnScaleEnd(const PinchGestureInput& aEvent);
473 :
474 : /**
475 : * Helper methods for handling pan events.
476 : */
477 : nsEventStatus OnPanMayBegin(const PanGestureInput& aEvent);
478 : nsEventStatus OnPanCancelled(const PanGestureInput& aEvent);
479 : nsEventStatus OnPanBegin(const PanGestureInput& aEvent);
480 : nsEventStatus OnPan(const PanGestureInput& aEvent, bool aFingersOnTouchpad);
481 : nsEventStatus OnPanEnd(const PanGestureInput& aEvent);
482 : nsEventStatus OnPanMomentumStart(const PanGestureInput& aEvent);
483 : nsEventStatus OnPanMomentumEnd(const PanGestureInput& aEvent);
484 : nsEventStatus HandleEndOfPan();
485 :
486 : /**
487 : * Helper methods for handling scroll wheel events.
488 : */
489 : nsEventStatus OnScrollWheel(const ScrollWheelInput& aEvent);
490 :
491 : ParentLayerPoint GetScrollWheelDelta(const ScrollWheelInput& aEvent) const;
492 :
493 : /**
494 : * Helper methods for handling keyboard events.
495 : */
496 : nsEventStatus OnKeyboard(const KeyboardInput& aEvent);
497 :
498 : CSSPoint GetKeyboardDestination(const KeyboardScrollAction& aAction) const;
499 :
500 : /**
501 : * Helper methods for long press gestures.
502 : */
503 : nsEventStatus OnLongPress(const TapGestureInput& aEvent);
504 : nsEventStatus OnLongPressUp(const TapGestureInput& aEvent);
505 :
506 : /**
507 : * Helper method for single tap gestures.
508 : */
509 : nsEventStatus OnSingleTapUp(const TapGestureInput& aEvent);
510 :
511 : /**
512 : * Helper method for a single tap confirmed.
513 : */
514 : nsEventStatus OnSingleTapConfirmed(const TapGestureInput& aEvent);
515 :
516 : /**
517 : * Helper method for double taps.
518 : */
519 : nsEventStatus OnDoubleTap(const TapGestureInput& aEvent);
520 :
521 : /**
522 : * Helper method for double taps where the double-tap gesture is disabled.
523 : */
524 : nsEventStatus OnSecondTap(const TapGestureInput& aEvent);
525 :
526 : /**
527 : * Helper method to cancel any gesture currently going to Gecko. Used
528 : * primarily when a user taps the screen over some clickable content but then
529 : * pans down instead of letting go (i.e. to cancel a previous touch so that a
530 : * new one can properly take effect.
531 : */
532 : nsEventStatus OnCancelTap(const TapGestureInput& aEvent);
533 :
534 : /**
535 : * Scrolls the viewport by an X,Y offset.
536 : */
537 : void ScrollBy(const CSSPoint& aOffset);
538 :
539 : /**
540 : * Scales the viewport by an amount (note that it multiplies this scale in to
541 : * the current scale, it doesn't set it to |aScale|). Also considers a focus
542 : * point so that the page zooms inward/outward from that point.
543 : */
544 : void ScaleWithFocus(float aScale,
545 : const CSSPoint& aFocus);
546 :
547 : /**
548 : * Schedules a composite on the compositor thread.
549 : */
550 : void ScheduleComposite();
551 :
552 : /**
553 : * Schedules a composite, and if enough time has elapsed since the last
554 : * paint, a paint.
555 : */
556 : void ScheduleCompositeAndMaybeRepaint();
557 :
558 : /**
559 : * Gets the displacement of the current touch since it began. That is, it is
560 : * the distance between the current position and the initial position of the
561 : * current touch (this only makes sense if a touch is currently happening and
562 : * OnTouchMove() or the equivalent for pan gestures is being invoked).
563 : * Note: It's an abuse of the 'Coord' class to use it to represent a 2D
564 : * distance, but it's the closest thing we currently have.
565 : */
566 : ScreenCoord PanDistance() const;
567 :
568 : /**
569 : * Gets the start point of the current touch.
570 : * Like PanDistance(), this only makes sense if a touch is currently
571 : * happening and OnTouchMove() or the equivalent for pan gestures is
572 : * being invoked.
573 : */
574 : ParentLayerPoint PanStart() const;
575 :
576 : /**
577 : * Gets a vector of the velocities of each axis.
578 : */
579 : const ParentLayerPoint GetVelocityVector() const;
580 :
581 : /**
582 : * Sets the velocities of each axis.
583 : */
584 : void SetVelocityVector(const ParentLayerPoint& aVelocityVector);
585 :
586 : /**
587 : * Gets the first touch point from a MultiTouchInput. This gets only
588 : * the first one and assumes the rest are either missing or not relevant.
589 : */
590 : ParentLayerPoint GetFirstTouchPoint(const MultiTouchInput& aEvent);
591 :
592 : /**
593 : * Sets the panning state basing on the pan direction angle and current touch-action value.
594 : */
595 : void HandlePanningWithTouchAction(double angle);
596 :
597 : /**
598 : * Sets the panning state ignoring the touch action value.
599 : */
600 : void HandlePanning(double angle);
601 :
602 : /**
603 : * Update the panning state and axis locks.
604 : */
605 : void HandlePanningUpdate(const ScreenPoint& aDelta);
606 :
607 : /**
608 : * Sets up anything needed for panning. This takes us out of the "TOUCHING"
609 : * state and starts actually panning us.
610 : */
611 : nsEventStatus StartPanning(const ParentLayerPoint& aStartPoint);
612 :
613 : /**
614 : * Wrapper for Axis::UpdateWithTouchAtDevicePoint(). Calls this function for
615 : * both axes and factors in the time delta from the last update.
616 : */
617 : void UpdateWithTouchAtDevicePoint(const MultiTouchInput& aEvent);
618 :
619 : /**
620 : * Does any panning required due to a new touch event.
621 : */
622 : void TrackTouch(const MultiTouchInput& aEvent);
623 :
624 : /**
625 : * Utility function to send updated FrameMetrics to Gecko so that it can paint
626 : * the displayport area. Calls into GeckoContentController to do the actual
627 : * work. This call will use the current metrics. If this function is called
628 : * from a non-main thread, it will redispatch itself to the main thread, and
629 : * use the latest metrics during the redispatch.
630 : */
631 : void RequestContentRepaint(bool aUserAction = true);
632 :
633 : /**
634 : * Send the provided metrics to Gecko to trigger a repaint. This function
635 : * may filter duplicate calls with the same metrics. This function must be
636 : * called on the main thread.
637 : */
638 : void RequestContentRepaint(const FrameMetrics& aFrameMetrics,
639 : const ParentLayerPoint& aVelocity);
640 :
641 : /**
642 : * Gets the current frame metrics. This is *not* the Gecko copy stored in the
643 : * layers code.
644 : */
645 : const FrameMetrics& GetFrameMetrics() const;
646 :
647 : /**
648 : * Gets the pointer to the apzc tree manager. All the access to tree manager
649 : * should be made via this method and not via private variable since this method
650 : * ensures that no lock is set.
651 : */
652 : APZCTreeManager* GetApzcTreeManager() const;
653 :
654 : /**
655 : * Convert ScreenPoint relative to the screen to LayoutDevicePoint relative
656 : * to the parent document. This excludes the transient compositor transform.
657 : * NOTE: This must be converted to LayoutDevicePoint relative to the child
658 : * document before sending over IPC to a child process.
659 : */
660 : bool ConvertToGecko(const ScreenIntPoint& aPoint, LayoutDevicePoint* aOut);
661 :
662 : enum AxisLockMode {
663 : FREE, /* No locking at all */
664 : STANDARD, /* Default axis locking mode that remains locked until pan ends*/
665 : STICKY, /* Allow lock to be broken, with hysteresis */
666 : };
667 :
668 : static AxisLockMode GetAxisLockMode();
669 :
670 : // Helper function for OnSingleTapUp(), OnSingleTapConfirmed(), and
671 : // OnLongPressUp().
672 : nsEventStatus GenerateSingleTap(GeckoContentController::TapType aType,
673 : const ScreenIntPoint& aPoint,
674 : mozilla::Modifiers aModifiers);
675 :
676 : // Common processing at the end of a touch block.
677 : void OnTouchEndOrCancel();
678 :
679 : uint64_t mLayersId;
680 : RefPtr<CompositorController> mCompositorController;
681 : RefPtr<MetricsSharingController> mMetricsSharingController;
682 :
683 : /* Access to the following two fields is protected by the mRefPtrMonitor,
684 : since they are accessed on the UI thread but can be cleared on the
685 : compositor thread. */
686 : RefPtr<GeckoContentController> mGeckoContentController;
687 : RefPtr<GestureEventListener> mGestureEventListener;
688 : mutable Monitor mRefPtrMonitor;
689 :
690 : // This is a raw pointer to avoid introducing a reference cycle between
691 : // AsyncPanZoomController and APZCTreeManager. Since these objects don't
692 : // live on the main thread, we can't use the cycle collector with them.
693 : // The APZCTreeManager owns the lifetime of the APZCs, so nulling this
694 : // pointer out in Destroy() will prevent accessing deleted memory.
695 : Atomic<APZCTreeManager*> mTreeManager;
696 :
697 : /* Utility functions that return a addrefed pointer to the corresponding fields. */
698 : already_AddRefed<GeckoContentController> GetGeckoContentController() const;
699 : already_AddRefed<GestureEventListener> GetGestureEventListener() const;
700 :
701 : PlatformSpecificStateBase* GetPlatformSpecificState();
702 :
703 : protected:
704 : // Both |mFrameMetrics| and |mLastContentPaintMetrics| are protected by the
705 : // monitor. Do not read from or modify either of them without locking.
706 : ScrollMetadata mScrollMetadata;
707 : FrameMetrics& mFrameMetrics; // for convenience, refers to mScrollMetadata.mMetrics
708 :
709 : // Protects |mFrameMetrics|, |mLastContentPaintMetrics|, and |mState|.
710 : // Before manipulating |mFrameMetrics| or |mLastContentPaintMetrics|, the
711 : // monitor should be held. When setting |mState|, either the SetState()
712 : // function can be used, or the monitor can be held and then |mState| updated.
713 : // IMPORTANT: See the note about lock ordering at the top of APZCTreeManager.h.
714 : // This is mutable to allow entering it from 'const' methods; doing otherwise
715 : // would significantly limit what methods could be 'const'.
716 : mutable ReentrantMonitor mMonitor;
717 :
718 : private:
719 : // Metadata of the container layer corresponding to this APZC. This is
720 : // stored here so that it is accessible from the UI/controller thread.
721 : // These are the metrics at last content paint, the most recent
722 : // values we were notified of in NotifyLayersUpdate(). Since it represents
723 : // the Gecko state, it should be used as a basis for untransformation when
724 : // sending messages back to Gecko.
725 : ScrollMetadata mLastContentPaintMetadata;
726 : FrameMetrics& mLastContentPaintMetrics; // for convenience, refers to mLastContentPaintMetadata.mMetrics
727 : // The last metrics used for a content repaint request.
728 : FrameMetrics mLastPaintRequestMetrics;
729 : // The metrics that we expect content to have. This is updated when we
730 : // request a content repaint, and when we receive a shadow layers update.
731 : // This allows us to transform events into Gecko's coordinate space.
732 : FrameMetrics mExpectedGeckoMetrics;
733 :
734 : // These variables cache the scroll offset and zoom stored in |mFrameMetrics|
735 : // the last time SampleCompositedAsyncTransform() was called.
736 : CSSPoint mCompositedScrollOffset;
737 : CSSToParentLayerScale2D mCompositedZoom;
738 :
739 : AxisX mX;
740 : AxisY mY;
741 :
742 : // This flag is set to true when we are in a axis-locked pan as a result of
743 : // the touch-action CSS property.
744 : bool mPanDirRestricted;
745 :
746 : // Most up-to-date constraints on zooming. These should always be reasonable
747 : // values; for example, allowing a min zoom of 0.0 can cause very bad things
748 : // to happen.
749 : ZoomConstraints mZoomConstraints;
750 :
751 : // The last time the compositor has sampled the content transform for this
752 : // frame.
753 : TimeStamp mLastSampleTime;
754 :
755 : // The last sample time at which we submitted a checkerboarding report.
756 : TimeStamp mLastCheckerboardReport;
757 :
758 : // Stores the previous focus point if there is a pinch gesture happening. Used
759 : // to allow panning by moving multiple fingers (thus moving the focus point).
760 : ParentLayerPoint mLastZoomFocus;
761 :
762 : RefPtr<AsyncPanZoomAnimation> mAnimation;
763 :
764 : UniquePtr<OverscrollEffectBase> mOverscrollEffect;
765 :
766 : // Groups state variables that are specific to a platform.
767 : // Initialized on first use.
768 : UniquePtr<PlatformSpecificStateBase> mPlatformSpecificState;
769 :
770 : friend class Axis;
771 :
772 : public:
773 : /**
774 : * Invoke |callable|, passing |mLastContentPaintMetrics| as argument,
775 : * while holding the APZC lock required to access |mLastContentPaintMetrics|.
776 : * This allows code outside of an AsyncPanZoomController method implementation
777 : * to access |mLastContentPaintMetrics| without having to make a copy of it.
778 : * Passes through the return value of |callable|.
779 : */
780 : template <typename Callable>
781 0 : auto CallWithLastContentPaintMetrics(const Callable& callable) const
782 : -> decltype(callable(mLastContentPaintMetrics)) {
783 0 : ReentrantMonitorAutoEnter lock(mMonitor);
784 0 : return callable(mLastContentPaintMetrics);
785 : }
786 :
787 : /* ===================================================================
788 : * The functions and members in this section are used to expose
789 : * the current async transform state to callers.
790 : */
791 : public:
792 : /**
793 : * Allows consumers of async transforms to specify for what purpose they are
794 : * using the async transform:
795 : *
796 : * |eForHitTesting| is intended for hit-testing and other uses that need
797 : * the most up-to-date transform, reflecting all events
798 : * that have been processed so far, even if the transform
799 : * is not yet reflected visually.
800 : * |eForCompositing| is intended for the transform that should be reflected
801 : * visually.
802 : *
803 : * For example, if an APZC has metrics with the mForceDisableApz flag set,
804 : * then the |eForCompositing| async transform will be empty, while the
805 : * |eForHitTesting| async transform will reflect processed input events
806 : * regardless of mForceDisableApz.
807 : */
808 : enum AsyncTransformConsumer {
809 : eForHitTesting,
810 : eForCompositing,
811 : };
812 :
813 : /**
814 : * Get the current scroll offset of the scrollable frame corresponding
815 : * to this APZC, including the effects of any asynchronous panning and
816 : * zooming, in ParentLayer pixels.
817 : */
818 : ParentLayerPoint GetCurrentAsyncScrollOffset(AsyncTransformConsumer aMode) const;
819 :
820 : /**
821 : * Get the current scroll offset of the scrollable frame corresponding
822 : * to this APZC, including the effects of any asynchronous panning, in
823 : * CSS pixels.
824 : */
825 : CSSPoint GetCurrentAsyncScrollOffsetInCssPixels(AsyncTransformConsumer aMode) const;
826 :
827 : /**
828 : * Return a visual effect that reflects this apzc's
829 : * overscrolled state, if any.
830 : */
831 : AsyncTransformComponentMatrix GetOverscrollTransform(AsyncTransformConsumer aMode) const;
832 :
833 : /**
834 : * Returns the incremental transformation corresponding to the async pan/zoom
835 : * in progress. That is, when this transform is multiplied with the layer's
836 : * existing transform, it will make the layer appear with the desired pan/zoom
837 : * amount.
838 : */
839 : AsyncTransform GetCurrentAsyncTransform(AsyncTransformConsumer aMode) const;
840 :
841 : /**
842 : * Returns the same transform as GetCurrentAsyncTransform(), but includes
843 : * any transform due to axis over-scroll.
844 : */
845 : AsyncTransformComponentMatrix GetCurrentAsyncTransformWithOverscroll(AsyncTransformConsumer aMode) const;
846 :
847 : private:
848 : /**
849 : * Samples the composited async transform, making the result of
850 : * |GetCurrentAsyncTransform(eForCompositing)| and similar functions reflect
851 : * the async scroll offset and zoom stored in |mFrameMetrics|.
852 : *
853 : * (This is only relevant when |gfxPrefs::APZFrameDelayEnabled() == true|.
854 : * Otherwise, GetCurrentAsyncTransform() always reflects what's stored in
855 : * |mFrameMetrics| immediately, without any delay.)
856 : */
857 : void SampleCompositedAsyncTransform();
858 :
859 : /*
860 : * Helper functions to query the async scroll offset and zoom either
861 : * directly from |mFrameMetrics|, or from cached variables that store
862 : * the scroll offset and zoom from the last time it was sampled by
863 : * calling SampleCompositedAsyncTransform(), depending on who is asking.
864 : */
865 : CSSPoint GetEffectiveScrollOffset(AsyncTransformConsumer aMode) const;
866 : CSSToParentLayerScale2D GetEffectiveZoom(AsyncTransformConsumer aMode) const;
867 :
868 : /* ===================================================================
869 : * The functions and members in this section are used to manage
870 : * the state that tracks what this APZC is doing with the input events.
871 : */
872 : protected:
873 : enum PanZoomState {
874 : NOTHING, /* no touch-start events received */
875 : FLING, /* all touches removed, but we're still scrolling page */
876 : TOUCHING, /* one touch-start event received */
877 :
878 : PANNING, /* panning the frame */
879 : PANNING_LOCKED_X, /* touch-start followed by move (i.e. panning with axis lock) X axis */
880 : PANNING_LOCKED_Y, /* as above for Y axis */
881 :
882 : PAN_MOMENTUM, /* like PANNING, but controlled by momentum PanGestureInput events */
883 :
884 : PINCHING, /* nth touch-start, where n > 1. this mode allows pan and zoom */
885 : ANIMATING_ZOOM, /* animated zoom to a new rect */
886 : OVERSCROLL_ANIMATION, /* Spring-based animation used to relieve overscroll once
887 : the finger is lifted. */
888 : SMOOTH_SCROLL, /* Smooth scrolling to destination. Used by
889 : CSSOM-View smooth scroll-behavior */
890 : WHEEL_SCROLL, /* Smooth scrolling to a destination for a wheel event. */
891 : KEYBOARD_SCROLL /* Smooth scrolling to a destination for a keyboard event. */
892 : };
893 :
894 : // This is in theory protected by |mMonitor|; that is, it should be held whenever
895 : // this is updated. In practice though... see bug 897017.
896 : PanZoomState mState;
897 :
898 : private:
899 : friend class StateChangeNotificationBlocker;
900 : /**
901 : * A counter of how many StateChangeNotificationBlockers are active.
902 : * A non-zero count will prevent state change notifications from
903 : * being dispatched. Only code that holds mMonitor should touch this.
904 : */
905 : int mNotificationBlockers;
906 :
907 : /**
908 : * Helper to set the current state. Holds the monitor before actually setting
909 : * it and fires content controller events based on state changes. Always set
910 : * the state using this call, do not set it directly.
911 : */
912 : void SetState(PanZoomState aState);
913 : /**
914 : * Fire content controller notifications about state changes, assuming no
915 : * StateChangeNotificationBlocker has been activated.
916 : */
917 : void DispatchStateChangeNotification(PanZoomState aOldState, PanZoomState aNewState);
918 : /**
919 : * Internal helpers for checking general state of this apzc.
920 : */
921 : static bool IsTransformingState(PanZoomState aState);
922 :
923 : /* ===================================================================
924 : * The functions and members in this section are used to manage
925 : * blocks of touch events and the state needed to deal with content
926 : * listeners.
927 : */
928 : public:
929 : /**
930 : * Flush a repaint request if one is needed, without throttling it with the
931 : * paint throttler.
932 : */
933 : void FlushRepaintForNewInputBlock();
934 :
935 : /**
936 : * Given the number of touch points in an input event and touch block they
937 : * belong to, check if the event can result in a panning/zooming behavior.
938 : * This is primarily used to figure out when to dispatch the pointercancel
939 : * event for the pointer events spec.
940 : */
941 : bool ArePointerEventsConsumable(TouchBlockState* aBlock, uint32_t aTouchPoints);
942 :
943 : /**
944 : * Clear internal state relating to touch input handling.
945 : */
946 : void ResetTouchInputState();
947 :
948 : /**
949 : * Gets a ref to the input queue that is shared across the entire tree manager.
950 : */
951 : const RefPtr<InputQueue>& GetInputQueue() const;
952 :
953 : private:
954 : void CancelAnimationAndGestureState();
955 :
956 : RefPtr<InputQueue> mInputQueue;
957 : InputBlockState* GetCurrentInputBlock() const;
958 : TouchBlockState* GetCurrentTouchBlock() const;
959 : bool HasReadyTouchBlock() const;
960 :
961 : PanGestureBlockState* GetCurrentPanGestureBlock() const;
962 :
963 : private:
964 : /* ===================================================================
965 : * The functions and members in this section are used to manage
966 : * fling animations, smooth scroll animations, and overscroll
967 : * during a fling or smooth scroll.
968 : */
969 : public:
970 : /**
971 : * Attempt a fling with the velocity specified in |aHandoffState|.
972 : * If we are not pannable, the fling is handed off to the next APZC in
973 : * the handoff chain via mTreeManager->DispatchFling().
974 : * Returns true iff. the entire velocity of the fling was consumed by
975 : * this APZC. |aHandoffState.mVelocity| is modified to contain any
976 : * unused, residual velocity.
977 : * |aHandoffState.mIsHandoff| should be true iff. the fling was handed off
978 : * from a previous APZC, and determines whether acceleration is applied
979 : * to the fling.
980 : */
981 : bool AttemptFling(FlingHandoffState& aHandoffState);
982 :
983 : private:
984 : friend class AndroidFlingAnimation;
985 : friend class GenericFlingAnimation;
986 : friend class OverscrollAnimation;
987 : friend class SmoothScrollAnimation;
988 : friend class GenericScrollAnimation;
989 : friend class WheelScrollAnimation;
990 : friend class KeyboardScrollAnimation;
991 :
992 : friend class GenericOverscrollEffect;
993 : friend class WidgetOverscrollEffect;
994 :
995 : // The initial velocity of the most recent fling.
996 : ParentLayerPoint mLastFlingVelocity;
997 : // The time at which the most recent fling started.
998 : TimeStamp mLastFlingTime;
999 : // Indicates if the repaint-during-pinch timer is currently set
1000 : bool mPinchPaintTimerSet;
1001 :
1002 : // Deal with overscroll resulting from a fling animation. This is only ever
1003 : // called on APZC instances that were actually performing a fling.
1004 : // The overscroll is handled by trying to hand the fling off to an APZC
1005 : // later in the handoff chain, or if there are no takers, continuing the
1006 : // fling and entering an overscrolled state.
1007 : void HandleFlingOverscroll(const ParentLayerPoint& aVelocity,
1008 : const RefPtr<const OverscrollHandoffChain>& aOverscrollHandoffChain,
1009 : const RefPtr<const AsyncPanZoomController>& aScrolledApzc);
1010 :
1011 : void HandleSmoothScrollOverscroll(const ParentLayerPoint& aVelocity);
1012 :
1013 : // Helper function used by AttemptFling().
1014 : void AcceptFling(FlingHandoffState& aHandoffState);
1015 :
1016 : // Start an overscroll animation with the given initial velocity.
1017 : void StartOverscrollAnimation(const ParentLayerPoint& aVelocity);
1018 :
1019 : void SmoothScrollTo(const CSSPoint& aDestination);
1020 :
1021 : // Returns whether overscroll is allowed during an event.
1022 : bool AllowScrollHandoffInCurrentBlock() const;
1023 :
1024 : // Invoked by the pinch repaint timer.
1025 : void DoDelayedRequestContentRepaint();
1026 :
1027 : /* ===================================================================
1028 : * The functions and members in this section are used to make ancestor chains
1029 : * out of APZC instances. These chains can only be walked or manipulated
1030 : * while holding the lock in the associated APZCTreeManager instance.
1031 : */
1032 : public:
1033 34 : void SetParent(AsyncPanZoomController* aParent) {
1034 34 : mParent = aParent;
1035 34 : }
1036 :
1037 15 : AsyncPanZoomController* GetParent() const {
1038 15 : return mParent;
1039 : }
1040 :
1041 : /* Returns true if there is no APZC higher in the tree with the same
1042 : * layers id.
1043 : */
1044 27 : bool HasNoParentWithSameLayersId() const {
1045 27 : return !mParent || (mParent->mLayersId != mLayersId);
1046 : }
1047 :
1048 0 : bool IsRootForLayersId() const {
1049 0 : ReentrantMonitorAutoEnter lock(mMonitor);
1050 0 : return mScrollMetadata.IsLayersIdRoot();
1051 : }
1052 :
1053 0 : bool IsRootContent() const {
1054 0 : ReentrantMonitorAutoEnter lock(mMonitor);
1055 0 : return mFrameMetrics.IsRootContent();
1056 : }
1057 :
1058 : private:
1059 : // |mTreeManager| belongs in this section but it's declaration is a bit
1060 : // further above due to initialization-order constraints.
1061 :
1062 : RefPtr<AsyncPanZoomController> mParent;
1063 :
1064 :
1065 : /* ===================================================================
1066 : * The functions and members in this section are used for scrolling,
1067 : * including handing off scroll to another APZC, and overscrolling.
1068 : */
1069 : public:
1070 0 : FrameMetrics::ViewID GetScrollHandoffParentId() const {
1071 0 : return mScrollMetadata.GetScrollParentId();
1072 : }
1073 :
1074 : /**
1075 : * Attempt to scroll in response to a touch-move from |aStartPoint| to
1076 : * |aEndPoint|, which are in our (transformed) screen coordinates.
1077 : * Due to overscroll handling, there may not actually have been a touch-move
1078 : * at these points, but this function will scroll as if there had been.
1079 : * If this attempt causes overscroll (i.e. the layer cannot be scrolled
1080 : * by the entire amount requested), the overscroll is passed back to the
1081 : * tree manager via APZCTreeManager::DispatchScroll(). If the tree manager
1082 : * does not find an APZC further in the handoff chain to accept the
1083 : * overscroll, and this APZC is pannable, this APZC enters an overscrolled
1084 : * state.
1085 : * |aOverscrollHandoffChain| and |aOverscrollHandoffChainIndex| are used by
1086 : * the tree manager to keep track of which APZC to hand off the overscroll
1087 : * to; this function increments the chain and the index and passes it on to
1088 : * APZCTreeManager::DispatchScroll() in the event of overscroll.
1089 : * Returns true iff. this APZC, or an APZC further down the
1090 : * handoff chain, accepted the scroll (possibly entering an overscrolled
1091 : * state). If this returns false, the caller APZC knows that it should enter
1092 : * an overscrolled state itself if it can.
1093 : * aStartPoint and aEndPoint are modified depending on how much of the
1094 : * scroll gesture was consumed by APZCs in the handoff chain.
1095 : */
1096 : bool AttemptScroll(ParentLayerPoint& aStartPoint,
1097 : ParentLayerPoint& aEndPoint,
1098 : OverscrollHandoffState& aOverscrollHandoffState);
1099 :
1100 : void FlushRepaintForOverscrollHandoff();
1101 :
1102 : /**
1103 : * If overscrolled, start a snap-back animation and return true.
1104 : * Otherwise return false.
1105 : */
1106 : bool SnapBackIfOverscrolled();
1107 :
1108 : /**
1109 : * Build the chain of APZCs along which scroll will be handed off when
1110 : * this APZC receives input events.
1111 : *
1112 : * Notes on lifetime and const-correctness:
1113 : * - The returned handoff chain is |const|, to indicate that it cannot be
1114 : * changed after being built.
1115 : * - When passing the chain to a function that uses it without storing it,
1116 : * pass it by reference-to-const (as in |const OverscrollHandoffChain&|).
1117 : * - When storing the chain, store it by RefPtr-to-const (as in
1118 : * |RefPtr<const OverscrollHandoffChain>|). This ensures the chain is
1119 : * kept alive. Note that queueing a task that uses the chain as an
1120 : * argument constitutes storing, as the task may outlive its queuer.
1121 : * - When passing the chain to a function that will store it, pass it as
1122 : * |const RefPtr<const OverscrollHandoffChain>&|. This allows the
1123 : * function to copy it into the |RefPtr<const OverscrollHandoffChain>|
1124 : * that will store it, while avoiding an unnecessary copy (and thus
1125 : * AddRef() and Release()) when passing it.
1126 : */
1127 : RefPtr<const OverscrollHandoffChain> BuildOverscrollHandoffChain();
1128 :
1129 : private:
1130 : /**
1131 : * A helper function for calling APZCTreeManager::DispatchScroll().
1132 : * Guards against the case where the APZC is being concurrently destroyed
1133 : * (and thus mTreeManager is being nulled out).
1134 : */
1135 : void CallDispatchScroll(ParentLayerPoint& aStartPoint,
1136 : ParentLayerPoint& aEndPoint,
1137 : OverscrollHandoffState& aOverscrollHandoffState);
1138 :
1139 : /**
1140 : * A helper function for overscrolling during panning. This is a wrapper
1141 : * around OverscrollBy() that also implements restrictions on entering
1142 : * overscroll based on the pan angle.
1143 : */
1144 : void OverscrollForPanning(ParentLayerPoint& aOverscroll,
1145 : const ScreenPoint& aPanDistance);
1146 :
1147 : /**
1148 : * Try to overscroll by 'aOverscroll'.
1149 : * If we are pannable on a particular axis, that component of 'aOverscroll'
1150 : * is transferred to any existing overscroll.
1151 : */
1152 : void OverscrollBy(ParentLayerPoint& aOverscroll);
1153 :
1154 :
1155 : /* ===================================================================
1156 : * The functions and members in this section are used to maintain the
1157 : * area that this APZC instance is responsible for. This is used when
1158 : * hit-testing to see which APZC instance should handle touch events.
1159 : */
1160 : public:
1161 34 : void SetAncestorTransform(const Matrix4x4& aTransformToLayer) {
1162 34 : mAncestorTransform = aTransformToLayer;
1163 34 : }
1164 :
1165 15 : Matrix4x4 GetAncestorTransform() const {
1166 15 : return mAncestorTransform;
1167 : }
1168 :
1169 : // Returns whether or not this apzc contains the given screen point within
1170 : // its composition bounds.
1171 : bool Contains(const ScreenIntPoint& aPoint) const;
1172 :
1173 58 : bool IsOverscrolled() const {
1174 58 : return mX.IsOverscrolled() || mY.IsOverscrolled();
1175 : }
1176 :
1177 : bool IsInPanningState() const;
1178 :
1179 : private:
1180 : /* This is the cumulative CSS transform for all the layers from (and including)
1181 : * the parent APZC down to (but excluding) this one, and excluding any
1182 : * perspective transforms. */
1183 : Matrix4x4 mAncestorTransform;
1184 :
1185 :
1186 : /* ===================================================================
1187 : * The functions and members in this section are used for sharing the
1188 : * FrameMetrics across processes for the progressive tiling code.
1189 : */
1190 : private:
1191 : /* Unique id assigned to each APZC. Used with ViewID to uniquely identify
1192 : * shared FrameMeterics used in progressive tile painting. */
1193 : const uint32_t mAPZCId;
1194 :
1195 : RefPtr<ipc::SharedMemoryBasic> mSharedFrameMetricsBuffer;
1196 : CrossProcessMutex* mSharedLock;
1197 : /**
1198 : * Called when ever mFrameMetrics is updated so that if it is being
1199 : * shared with the content process the shared FrameMetrics may be updated.
1200 : */
1201 : void UpdateSharedCompositorFrameMetrics();
1202 : /**
1203 : * Create a shared memory buffer for containing the FrameMetrics and
1204 : * a CrossProcessMutex that may be shared with the content process
1205 : * for use in progressive tiled update calculations.
1206 : */
1207 : void ShareCompositorFrameMetrics();
1208 :
1209 :
1210 : /* ===================================================================
1211 : * The functions and members in this section are used for testing
1212 : * and assertion purposes only.
1213 : */
1214 : public:
1215 : /**
1216 : * Set an extra offset for testing async scrolling.
1217 : */
1218 0 : void SetTestAsyncScrollOffset(const CSSPoint& aPoint)
1219 : {
1220 0 : mTestAsyncScrollOffset = aPoint;
1221 0 : }
1222 : /**
1223 : * Set an extra offset for testing async scrolling.
1224 : */
1225 0 : void SetTestAsyncZoom(const LayerToParentLayerScale& aZoom)
1226 : {
1227 0 : mTestAsyncZoom = aZoom;
1228 0 : }
1229 :
1230 40 : void MarkAsyncTransformAppliedToContent()
1231 : {
1232 40 : mAsyncTransformAppliedToContent = true;
1233 40 : }
1234 :
1235 0 : bool GetAsyncTransformAppliedToContent() const
1236 : {
1237 0 : return mAsyncTransformAppliedToContent;
1238 : }
1239 :
1240 7 : uint64_t GetLayersId() const
1241 : {
1242 7 : return mLayersId;
1243 : }
1244 :
1245 : private:
1246 : // Extra offset to add to the async scroll position for testing
1247 : CSSPoint mTestAsyncScrollOffset;
1248 : // Extra zoom to include in the aync zoom for testing
1249 : LayerToParentLayerScale mTestAsyncZoom;
1250 : // Flag to track whether or not the APZ transform is not used. This
1251 : // flag is recomputed for every composition frame.
1252 : bool mAsyncTransformAppliedToContent;
1253 :
1254 :
1255 : /* ===================================================================
1256 : * The functions and members in this section are used for checkerboard
1257 : * recording.
1258 : */
1259 : private:
1260 : // Helper function to update the in-progress checkerboard event, if any.
1261 : void UpdateCheckerboardEvent(const MutexAutoLock& aProofOfLock,
1262 : uint32_t aMagnitude);
1263 :
1264 : // Mutex protecting mCheckerboardEvent
1265 : Mutex mCheckerboardEventLock;
1266 : // This is created when this APZC instance is first included as part of a
1267 : // composite. If a checkerboard event takes place, this is destroyed at the
1268 : // end of the event, and a new one is created on the next composite.
1269 : UniquePtr<CheckerboardEvent> mCheckerboardEvent;
1270 : // This is used to track the total amount of time that we could reasonably
1271 : // be checkerboarding. Combined with other info, this allows us to meaningfully
1272 : // say how frequently users actually encounter checkerboarding.
1273 : PotentialCheckerboardDurationTracker mPotentialCheckerboardTracker;
1274 :
1275 :
1276 : /* ===================================================================
1277 : * The functions in this section are used for CSS scroll snapping.
1278 : */
1279 :
1280 : // If |aEvent| should trigger scroll snapping, adjust |aDelta| to reflect
1281 : // the snapping (that is, make it a delta that will take us to the desired
1282 : // snap point). The delta is interpreted as being relative to
1283 : // |aStartPosition|, and if a target snap point is found, |aStartPosition|
1284 : // is also updated, to the value of the snap point.
1285 : // Returns true iff. a target snap point was found.
1286 : bool MaybeAdjustDeltaForScrollSnapping(const ScrollWheelInput& aEvent,
1287 : ParentLayerPoint& aDelta,
1288 : CSSPoint& aStartPosition);
1289 :
1290 : // Snap to a snap position nearby the current scroll position, if appropriate.
1291 : void ScrollSnap();
1292 :
1293 : // Snap to a snap position nearby the destination predicted based on the
1294 : // current velocity, if appropriate.
1295 : void ScrollSnapToDestination();
1296 :
1297 : // Snap to a snap position nearby the provided destination, if appropriate.
1298 : void ScrollSnapNear(const CSSPoint& aDestination);
1299 :
1300 : // Find a snap point near |aDestination| that we should snap to.
1301 : // Returns the snap point if one was found, or an empty Maybe otherwise.
1302 : // |aUnit| affects the snapping behaviour (see ScrollSnapUtils::
1303 : // GetSnapPointForDestination). It should generally be determined by the
1304 : // type of event that's triggering the scroll.
1305 : Maybe<CSSPoint> FindSnapPointNear(const CSSPoint& aDestination,
1306 : nsIScrollableFrame::ScrollUnit aUnit);
1307 : };
1308 :
1309 : } // namespace layers
1310 : } // namespace mozilla
1311 :
1312 : #endif // mozilla_layers_PanZoomController_h
|