/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set sw=2 ts=8 et tw=80 : */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef mozilla_layers_AsyncPanZoomController_h #define mozilla_layers_AsyncPanZoomController_h #include "CrossProcessMutex.h" #include "GeckoContentController.h" #include "mozilla/Attributes.h" #include "mozilla/EventForwards.h" #include "mozilla/Monitor.h" #include "mozilla/ReentrantMonitor.h" #include "mozilla/RefPtr.h" #include "mozilla/Atomics.h" #include "InputData.h" #include "Axis.h" #include "TaskThrottler.h" #include "gfx3DMatrix.h" #include "base/message_loop.h" namespace mozilla { namespace ipc { class SharedMemoryBasic; } namespace layers { struct ScrollableLayerGuid; class CompositorParent; class GestureEventListener; class ContainerLayer; class PCompositorParent; class ViewTransform; class APZCTreeManager; class AsyncPanZoomAnimation; /** * Controller for all panning and zooming logic. Any time a user input is * detected and it must be processed in some way to affect what the user sees, * it goes through here. Listens for any input event from InputData and can * optionally handle WidgetGUIEvent-derived touch events, but this must be done * on the main thread. Note that this class completely cross-platform. * * Input events originate on the UI thread of the platform that this runs on, * and are then sent to this class. This class processes the event in some way; * for example, a touch move will usually lead to a panning of content (though * of course there are exceptions, such as if content preventDefaults the event, * or if the target frame is not scrollable). The compositor interacts with this * class by locking it and querying it for the current transform matrix based on * the panning and zooming logic that was invoked on the UI thread. * * Currently, each outer DOM window (i.e. a website in a tab, but not any * subframes) has its own AsyncPanZoomController. In the future, to support * asynchronously scrolled subframes, we want to have one AsyncPanZoomController * per frame. */ class AsyncPanZoomController { NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AsyncPanZoomController) typedef mozilla::MonitorAutoLock MonitorAutoLock; typedef uint32_t TouchBehaviorFlags; public: enum GestureBehavior { // The platform code is responsible for forwarding gesture events here. We // will not attempt to generate gesture events from MultiTouchInputs. DEFAULT_GESTURES, // An instance of GestureEventListener is used to detect gestures. This is // handled completely internally within this class. USE_GESTURE_DETECTOR }; /** * Constant describing the tolerance in distance we use, multiplied by the * device DPI, before we start panning the screen. This is to prevent us from * accidentally processing taps as touch moves, and from very short/accidental * touches moving the screen. */ static float GetTouchStartTolerance(); AsyncPanZoomController(uint64_t aLayersId, APZCTreeManager* aTreeManager, GeckoContentController* aController, GestureBehavior aGestures = DEFAULT_GESTURES); ~AsyncPanZoomController(); // -------------------------------------------------------------------------- // These methods must only be called on the gecko thread. // /** * Read the various prefs and do any global initialization for all APZC instances. * This must be run on the gecko thread before any APZC instances are actually * used for anything meaningful. */ static void InitializeGlobalState(); // -------------------------------------------------------------------------- // These methods must only be called on the controller/UI thread. // /** * General handler for incoming input events. Manipulates the frame metrics * based on what type of input it is. For example, a PinchGestureEvent will * cause scaling. This should only be called externally to this class. * HandleInputEvent() should be used internally. */ nsEventStatus ReceiveInputEvent(const InputData& aEvent); /** * Kicks an animation to zoom to a rect. This may be either a zoom out or zoom * in. The actual animation is done on the compositor thread after being set * up. */ void ZoomToRect(CSSRect aRect); /** * If we have touch listeners, this should always be called when we know * definitively whether or not content has preventDefaulted any touch events * that have come in. If |aPreventDefault| is true, any touch events in the * queue will be discarded. */ void ContentReceivedTouch(bool aPreventDefault); /** * Updates any zoom constraints contained in the tag. */ void UpdateZoomConstraints(const ZoomConstraints& aConstraints); /** * Return the zoom constraints last set for this APZC (in the constructor * or in UpdateZoomConstraints()). */ ZoomConstraints GetZoomConstraints() const; /** * Schedules a runnable to run on the controller/UI thread at some time * in the future. */ void PostDelayedTask(Task* aTask, int aDelayMs); // -------------------------------------------------------------------------- // These methods must only be called on the compositor thread. // bool UpdateAnimation(const TimeStamp& aSampleTime); /** * The compositor calls this when it's about to draw pannable/zoomable content * and is setting up transforms for compositing the layer tree. This is not * idempotent. For example, a fling transform can be applied each time this is * called (though not necessarily). |aSampleTime| is the time that this is * sampled at; this is used for interpolating animations. Calling this sets a * new transform in |aNewTransform| which should be multiplied to the transform * in the shadow layer corresponding to this APZC. * * Return value indicates whether or not any currently running animation * should continue. That is, if true, the compositor should schedule another * composite. */ bool SampleContentTransformForFrame(const TimeStamp& aSampleTime, ViewTransform* aNewTransform, ScreenPoint& aScrollOffset); /** * A shadow layer update has arrived. |aLayerMetrics| is the new FrameMetrics * for the container layer corresponding to this APZC. * |aIsFirstPaint| is a flag passed from the shadow * layers code indicating that the frame metrics being sent with this call are * the initial metrics and the initial paint of the frame has just happened. */ void NotifyLayersUpdated(const FrameMetrics& aLayerMetrics, bool aIsFirstPaint); /** * The platform implementation must set the compositor parent so that we can * request composites. */ void SetCompositorParent(CompositorParent* aCompositorParent); /** * The platform implementation must set the cross process compositor if * there is one associated with the layer tree. The cross process compositor * allows the APZC to share its FrameMetrics with the content process. * The shared FrameMetrics is used in progressive paint updates. */ void SetCrossProcessCompositorParent(PCompositorParent* aCrossProcessCompositorParent); // -------------------------------------------------------------------------- // These methods can be called from any thread. // /** * Shut down the controller/UI thread state and prepare to be * deleted (which may happen from any thread). */ void Destroy(); /** * Returns true if Destroy() has already been called on this APZC instance. */ bool IsDestroyed(); /** * Returns the incremental transformation corresponding to the async pan/zoom * in progress. That is, when this transform is multiplied with the layer's * existing transform, it will make the layer appear with the desired pan/zoom * amount. */ ViewTransform GetCurrentAsyncTransform(); /** * Returns the part of the async transform that will remain once Gecko does a * repaint at the desired metrics. That is, in the steady state: * gfx3DMatrix(GetCurrentAsyncTransform()) === GetNontransientAsyncTransform() */ gfx3DMatrix GetNontransientAsyncTransform(); /** * Returns the transform to take something from the coordinate space of the * last thing we know gecko painted, to the coordinate space of the last thing * we asked gecko to paint. In cases where that last request has not yet been * processed, this is needed to transform input events properly into a space * gecko will understand. */ gfx3DMatrix GetTransformToLastDispatchedPaint(); /** * Recalculates the displayport. Ideally, this should paint an area bigger * than the composite-to dimensions so that when you scroll down, you don't * checkerboard immediately. This includes a bunch of logic, including * algorithms to bias painting in the direction of the velocity. */ static const CSSRect CalculatePendingDisplayPort( const FrameMetrics& aFrameMetrics, const ScreenPoint& aVelocity, double aEstimatedPaintDuration); /** * Send an mozbrowserasyncscroll event. * *** The monitor must be held while calling this. */ void SendAsyncScrollEvent(); /** * Handler for events which should not be intercepted by the touch listener. * Does the work for ReceiveInputEvent(). */ nsEventStatus HandleInputEvent(const InputData& aEvent); /** * Populates the provided object (if non-null) with the scrollable guid of this apzc. */ void GetGuid(ScrollableLayerGuid* aGuidOut); /** * Returns the scrollable guid of this apzc. */ ScrollableLayerGuid GetGuid(); /** * Returns true if this APZC instance is for the layer identified by the guid. */ bool Matches(const ScrollableLayerGuid& aGuid); /** * Sync panning and zooming animation using a fixed frame time. * This will ensure that we animate the APZC correctly with other external * animations to the same timestamp. */ static void SetFrameTime(const TimeStamp& aMilliseconds); void StartAnimation(AsyncPanZoomAnimation* aAnimation); /** * Cancels any currently running animation. Note that all this does is set the * state of the AsyncPanZoomController back to NOTHING, but it is the * animation's responsibility to check this before advancing. */ void CancelAnimation(); /** * Attempt to scroll in response to a touch-move from |aStartPoint| to * |aEndPoint|, which are in our (transformed) screen coordinates. * Due to overscroll handling, there may not actually have been a touch-move * at these points, but this function will scroll as if there had been. * If this attempt causes overscroll (i.e. the layer cannot be scrolled * by the entire amount requested), the overscroll is passed back to the * tree manager via APZCTreeManager::DispatchScroll(). * |aOverscrollHandoffChainIndex| is used by the tree manager to keep track * of which APZC to hand off the overscroll to; this function increments it * and passes it on to APZCTreeManager::DispatchScroll() in the event of * overscroll. */ void AttemptScroll(const ScreenPoint& aStartPoint, const ScreenPoint& aEndPoint, uint32_t aOverscrollHandoffChainIndex = 0); /** * Returns allowed touch behavior for the given point on the scrollable layer. * Internally performs a kind of hit testing based on the regions constructed * on the main thread and attached to the current scrollable layer. Each of such regions * contains info about allowed touch behavior. If regions info isn't enough it returns * UNKNOWN value and we should switch to the fallback approach - asking content. * TODO: for now it's only a stub and returns hardcoded magic value. As soon as bug 928833 * is done we should integrate its logic here. */ TouchBehaviorFlags GetAllowedTouchBehavior(ScreenIntPoint& aPoint); /** * Sets allowed touch behavior for current touch session. * This method is invoked by the APZCTreeManager which in its turn invoked by * the widget after performing touch-action values retrieving. */ void SetAllowedTouchBehavior(const nsTArray& aBehaviors); /** * A helper function for calling APZCTreeManager::DispatchScroll(). * Guards against the case where the APZC is being concurrently destroyed * (and thus mTreeManager is being nulled out). */ void CallDispatchScroll(const ScreenPoint& aStartPoint, const ScreenPoint& aEndPoint, uint32_t aOverscrollHandoffChainIndex); /** * Returns whether this APZC is for an element marked with the 'scrollgrab' * attribute. */ bool HasScrollgrab() const { return mFrameMetrics.mHasScrollgrab; } void FlushRepaintForOverscrollHandoff(); protected: /** * Helper method for touches beginning. Sets everything up for panning and any * multitouch gestures. */ nsEventStatus OnTouchStart(const MultiTouchInput& aEvent); /** * Helper method for touches moving. Does any transforms needed when panning. */ nsEventStatus OnTouchMove(const MultiTouchInput& aEvent); /** * Helper method for touches ending. Redraws the screen if necessary and does * any cleanup after a touch has ended. */ nsEventStatus OnTouchEnd(const MultiTouchInput& aEvent); /** * Helper method for touches being cancelled. Treated roughly the same as a * touch ending (OnTouchEnd()). */ nsEventStatus OnTouchCancel(const MultiTouchInput& aEvent); /** * Helper method for scales beginning. Distinct from the OnTouch* handlers in * that this implies some outside implementation has determined that the user * is pinching. */ nsEventStatus OnScaleBegin(const PinchGestureInput& aEvent); /** * Helper method for scaling. As the user moves their fingers when pinching, * this changes the scale of the page. */ nsEventStatus OnScale(const PinchGestureInput& aEvent); /** * Helper method for scales ending. Redraws the screen if necessary and does * any cleanup after a scale has ended. */ nsEventStatus OnScaleEnd(const PinchGestureInput& aEvent); /** * Helper methods for long press gestures. */ nsEventStatus OnLongPress(const TapGestureInput& aEvent); nsEventStatus OnLongPressUp(const TapGestureInput& aEvent); /** * Helper method for single tap gestures. */ nsEventStatus OnSingleTapUp(const TapGestureInput& aEvent); /** * Helper method for a single tap confirmed. */ nsEventStatus OnSingleTapConfirmed(const TapGestureInput& aEvent); /** * Helper method for double taps. */ nsEventStatus OnDoubleTap(const TapGestureInput& aEvent); /** * Helper method to cancel any gesture currently going to Gecko. Used * primarily when a user taps the screen over some clickable content but then * pans down instead of letting go (i.e. to cancel a previous touch so that a * new one can properly take effect. */ nsEventStatus OnCancelTap(const TapGestureInput& aEvent); /** * Scrolls the viewport by an X,Y offset. */ void ScrollBy(const CSSPoint& aOffset); /** * Scales the viewport by an amount (note that it multiplies this scale in to * the current scale, it doesn't set it to |aScale|). Also considers a focus * point so that the page zooms inward/outward from that point. */ void ScaleWithFocus(float aScale, const CSSPoint& aFocus); /** * Schedules a composite on the compositor thread. Wrapper for * CompositorParent::ScheduleRenderOnCompositorThread(). */ void ScheduleComposite(); /** * Gets the displacement of the current touch since it began. That is, it is * the distance between the current position and the initial position of the * current touch (this only makes sense if a touch is currently happening and * OnTouchMove() is being invoked). */ float PanDistance(); /** * Gets a vector of the velocities of each axis. */ const ScreenPoint GetVelocityVector(); /** * Gets a reference to the first touch point from a MultiTouchInput. This * gets only the first one and assumes the rest are either missing or not * relevant. */ ScreenIntPoint& GetFirstTouchScreenPoint(const MultiTouchInput& aEvent); /** * Sets the panning state basing on the pan direction angle and current touch-action value. */ void HandlePanningWithTouchAction(double angle, TouchBehaviorFlags value); /** * Sets the panning state ignoring the touch action value. */ void HandlePanning(double angle); /** * Sets up anything needed for panning. This takes us out of the "TOUCHING" * state and starts actually panning us. */ nsEventStatus StartPanning(const MultiTouchInput& aStartPoint); /** * Wrapper for Axis::UpdateWithTouchAtDevicePoint(). Calls this function for * both axes and factors in the time delta from the last update. */ void UpdateWithTouchAtDevicePoint(const MultiTouchInput& aEvent); /** * Does any panning required due to a new touch event. */ void TrackTouch(const MultiTouchInput& aEvent); /** * Utility function to send updated FrameMetrics to Gecko so that it can paint * the displayport area. Calls into GeckoContentController to do the actual * work. Note that only one paint request can be active at a time. If a paint * request is made while a paint is currently happening, it gets queued up. If * a new paint request arrives before a paint is completed, the old request * gets discarded. */ void RequestContentRepaint(); /** * Tell the paint throttler to request a content repaint with the given * metrics. (Helper function used by RequestContentRepaint.) */ void RequestContentRepaint(FrameMetrics& aFrameMetrics); /** * Actually send the next pending paint request to gecko. */ void DispatchRepaintRequest(const FrameMetrics& aFrameMetrics); /** * Advances a fling by an interpolated amount based on the passed in |aDelta|. * This should be called whenever sampling the content transform for this * frame. Returns true if the fling animation should be advanced by one frame, * or false if there is no fling or the fling has ended. */ bool DoFling(const TimeDuration& aDelta); /** * Gets the current frame metrics. This is *not* the Gecko copy stored in the * layers code. */ const FrameMetrics& GetFrameMetrics(); /** * Sets the timer for content response to a series of touch events, if it * hasn't been already. This is to prevent us from batching up touch events * indefinitely in the case that content doesn't respond with whether or not * it wants to preventDefault. When the timer is fired, the touch event queue * will be flushed. */ void SetContentResponseTimer(); /** * Timeout function for content response. This should be called on a timer * after we get our first touch event in a batch, under the condition that we * waiting for response from content. If a notification comes indicating whether or not * content preventDefaulted a series of touch events and touch behavior values are * set before the timeout, the timeout should be cancelled. */ void TimeoutContentResponse(); /** * Timeout function for mozbrowserasyncscroll event. Because we throttle * mozbrowserasyncscroll events in some conditions, this function ensures * that the last mozbrowserasyncscroll event will be fired after a period of * time. */ void FireAsyncScrollOnTimeout(); private: enum PanZoomState { NOTHING, /* no touch-start events received */ FLING, /* all touches removed, but we're still scrolling page */ TOUCHING, /* one touch-start event received */ PANNING, /* panning the frame */ PANNING_LOCKED_X, /* touch-start followed by move (i.e. panning with axis lock) X axis */ PANNING_LOCKED_Y, /* as above for Y axis */ CROSS_SLIDING_X, /* Panning disabled while user does a horizontal gesture on a vertically-scrollable view. This used for the Windows Metro "cross-slide" gesture. */ CROSS_SLIDING_Y, /* as above for Y axis */ PINCHING, /* nth touch-start, where n > 1. this mode allows pan and zoom */ ANIMATING_ZOOM, /* animated zoom to a new rect */ WAITING_CONTENT_RESPONSE, /* a state halfway between NOTHING and TOUCHING - the user has put a finger down, but we don't yet know if a touch listener has prevented the default actions yet and the allowed touch behavior was not set yet. we still need to abort animations. */ }; /* * Returns whether current touch behavior values allow zooming. */ bool TouchActionAllowZoom(); /* * Returns allowed touch behavior from the mAllowedTouchBehavior array. * In case apzc didn't receive touch behavior values within the timeout * it returns default value. */ TouchBehaviorFlags GetTouchBehavior(uint32_t touchIndex); /** * To move from the WAITING_CONTENT_RESPONSE state to TOUCHING one we need two * conditions set: get content listeners response (whether they called preventDefault) * and get allowed touch behaviors. * This method checks both conditions and changes (or not changes) state * appropriately. */ void CheckContentResponse(); /** * Helper to set the current state. Holds the monitor before actually setting * it and fires content controller events based on state changes. Always set * the state using this call, do not set it directly. */ void SetState(PanZoomState aState); /** * Convert ScreenPoint relative to this APZC to CSSIntPoint relative * to the parent document. This excludes the transient compositor transform. * NOTE: This must be converted to CSSIntPoint relative to the child * document before sending over IPC. */ bool ConvertToGecko(const ScreenPoint& aPoint, CSSIntPoint* aOut); /** * Internal helpers for checking general state of this apzc. */ bool IsTransformingState(PanZoomState aState); bool IsPanningState(PanZoomState mState); bool AllowZoom(); enum AxisLockMode { FREE, /* No locking at all */ STANDARD, /* Default axis locking mode that remains locked until pan ends*/ STICKY, /* Allow lock to be broken, with hysteresis */ }; static AxisLockMode GetAxisLockMode(); uint64_t mLayersId; nsRefPtr mCompositorParent; PCompositorParent* mCrossProcessCompositorParent; TaskThrottler mPaintThrottler; /* Access to the following two fields is protected by the mRefPtrMonitor, since they are accessed on the UI thread but can be cleared on the compositor thread. */ nsRefPtr mGeckoContentController; nsRefPtr mGestureEventListener; Monitor mRefPtrMonitor; /* Utility functions that return a addrefed pointer to the corresponding fields. */ already_AddRefed GetGeckoContentController(); already_AddRefed GetGestureEventListener(); protected: // Both |mFrameMetrics| and |mLastContentPaintMetrics| are protected by the // monitor. Do not read from or modify either of them without locking. FrameMetrics mFrameMetrics; // Protects |mFrameMetrics|, |mLastContentPaintMetrics|, and |mState|. // Before manipulating |mFrameMetrics| or |mLastContentPaintMetrics|, the // monitor should be held. When setting |mState|, either the SetState() // function can be used, or the monitor can be held and then |mState| updated. ReentrantMonitor mMonitor; // Specifies whether we should use touch-action css property. Initialized from // the preferences. This property (in comparison with the global one) simplifies // testing apzc with (and without) touch-action property enabled concurrently // (e.g. with the gtest framework). bool mTouchActionPropertyEnabled; private: // Metrics of the container layer corresponding to this APZC. This is // stored here so that it is accessible from the UI/controller thread. // These are the metrics at last content paint, the most recent // values we were notified of in NotifyLayersUpdate(). Since it represents // the Gecko state, it should be used as a basis for untransformation when // sending messages back to Gecko. FrameMetrics mLastContentPaintMetrics; // The last metrics that we requested a paint for. These are used to make sure // that we're not requesting a paint of the same thing that's already drawn. // If we don't do this check, we don't get a ShadowLayersUpdated back. FrameMetrics mLastPaintRequestMetrics; // The last metrics that we actually sent to Gecko. This allows us to transform // inputs into a coordinate space that Gecko knows about. This assumes the pipe // through which input events and repaint requests are sent to Gecko operates // in a FIFO manner. FrameMetrics mLastDispatchedPaintMetrics; nsTArray mTouchQueue; CancelableTask* mContentResponseTimeoutTask; AxisX mX; AxisY mY; // This flag is set to true when we are in a axis-locked pan as a result of // the touch-action CSS property. bool mPanDirRestricted; // Most up-to-date constraints on zooming. These should always be reasonable // values; for example, allowing a min zoom of 0.0 can cause very bad things // to happen. ZoomConstraints mZoomConstraints; // The last time the compositor has sampled the content transform for this // frame. TimeStamp mLastSampleTime; // The last time a touch event came through on the UI thread. uint32_t mLastEventTime; // Stores the previous focus point if there is a pinch gesture happening. Used // to allow panning by moving multiple fingers (thus moving the focus point). ScreenPoint mLastZoomFocus; // Stores the state of panning and zooming this frame. This is protected by // |mMonitor|; that is, it should be held whenever this is updated. PanZoomState mState; // The last time and offset we fire the mozbrowserasyncscroll event when // compositor has sampled the content transform for this frame. TimeStamp mLastAsyncScrollTime; CSSPoint mLastAsyncScrollOffset; // The current offset drawn on the screen, it may not be sent since we have // throttling policy for mozbrowserasyncscroll event. CSSPoint mCurrentAsyncScrollOffset; // The delay task triggered by the throttling mozbrowserasyncscroll event // ensures the last mozbrowserasyncscroll event is always been fired. CancelableTask* mAsyncScrollTimeoutTask; // Flag used to determine whether or not we should try to enter the // WAITING_LISTENERS state. This is used in the case that we are processing a // queued up event block. If set, this means that we are handling this queue // and we don't want to queue the events back up again. bool mHandlingTouchQueue; // Values of allowed touch behavior for current touch points. // Since there are maybe a few current active touch points per time (multitouch case) // and each touch point should have its own value of allowed touch behavior- we're // keeping an array of allowed touch behavior values, not the single value. nsTArray mAllowedTouchBehaviors; // Specifies whether mAllowedTouchBehaviors is set for current touch events block. bool mAllowedTouchBehaviorSet; // Flag used to specify that content prevented the default behavior of the current // touch events block. bool mPreventDefault; // Specifies whether mPreventDefault property is set for current touch events block. bool mPreventDefaultSet; RefPtr mAnimation; friend class Axis; /* The functions and members in this section are used to build a tree * structure out of APZC instances. This tree can only be walked or * manipulated while holding the lock in the associated APZCTreeManager * instance. */ public: void SetLastChild(AsyncPanZoomController* child) { mLastChild = child; if (child) { child->mParent = this; } } void SetPrevSibling(AsyncPanZoomController* sibling) { mPrevSibling = sibling; if (sibling) { sibling->mParent = mParent; } } AsyncPanZoomController* GetLastChild() const { return mLastChild; } AsyncPanZoomController* GetPrevSibling() const { return mPrevSibling; } AsyncPanZoomController* GetParent() const { return mParent; } /* Returns true if there is no APZC higher in the tree with the same * layers id. */ bool IsRootForLayersId() const { return !mParent || (mParent->mLayersId != mLayersId); } bool IsRootForLayersId(const uint64_t& aLayersId) const { return (mLayersId == aLayersId) && IsRootForLayersId(); } private: // This is a raw pointer to avoid introducing a reference cycle between // AsyncPanZoomController and APZCTreeManager. Since these objects don't // live on the main thread, we can't use the cycle collector with them. // The APZCTreeManager owns the lifetime of the APZCs, so nulling this // pointer out in Destroy() will prevent accessing deleted memory. Atomic mTreeManager; nsRefPtr mLastChild; nsRefPtr mPrevSibling; nsRefPtr mParent; /* The functions and members in this section are used to maintain the * area that this APZC instance is responsible for. This is used when * hit-testing to see which APZC instance should handle touch events. */ public: void SetLayerHitTestData(const ScreenRect& aRect, const gfx3DMatrix& aTransformToLayer, const gfx3DMatrix& aTransformForLayer) { mVisibleRect = aRect; mAncestorTransform = aTransformToLayer; mCSSTransform = aTransformForLayer; } gfx3DMatrix GetAncestorTransform() const { return mAncestorTransform; } gfx3DMatrix GetCSSTransform() const { return mCSSTransform; } bool VisibleRegionContains(const ScreenPoint& aPoint) const { return mVisibleRect.Contains(aPoint); } private: /* Unique id assigned to each APZC. Used with ViewID to uniquely identify * shared FrameMeterics used in progressive tile painting. */ const uint32_t mAPZCId; /* This is the visible region of the layer that this APZC corresponds to, in * that layer's screen pixels (the same coordinate system in which this APZC * receives events in ReceiveInputEvent()). */ ScreenRect mVisibleRect; /* This is the cumulative CSS transform for all the layers between the parent * APZC and this one (not inclusive) */ gfx3DMatrix mAncestorTransform; /* This is the CSS transform for this APZC's layer. */ gfx3DMatrix mCSSTransform; ipc::SharedMemoryBasic* mSharedFrameMetricsBuffer; CrossProcessMutex* mSharedLock; /** * Called when ever mFrameMetrics is updated so that if it is being * shared with the content process the shared FrameMetrics may be updated. */ void UpdateSharedCompositorFrameMetrics(); /** * Create a shared memory buffer for containing the FrameMetrics and * a CrossProcessMutex that may be shared with the content process * for use in progressive tiled update calculations. */ void ShareCompositorFrameMetrics(); }; class AsyncPanZoomAnimation { NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AsyncPanZoomAnimation) public: AsyncPanZoomAnimation(const TimeDuration& aRepaintInterval = TimeDuration::Forever()) : mRepaintInterval(aRepaintInterval) { } virtual ~AsyncPanZoomAnimation() { } virtual bool Sample(FrameMetrics& aFrameMetrics, const TimeDuration& aDelta) = 0; /** * Specifies how frequently (at most) we want to do repaints during the * animation sequence. TimeDuration::Forever() will cause it to only repaint * at the end of the animation. */ TimeDuration mRepaintInterval; }; } } #endif // mozilla_layers_PanZoomController_h