Platform/GFX/APZ: Difference between revisions
No edit summary |
|||
Line 52: | Line 52: | ||
** a request to zoom in to a rectangle (APZCTreeManager::ZoomToRect()) | ** a request to zoom in to a rectangle (APZCTreeManager::ZoomToRect()) | ||
In addition, the widget code provides APZ with an interface for interacting with Gecko, called '''[https://mxr.mozilla.org/mozilla-central/source/gfx/layers/ipc/GeckoContentController.h GeckoContentController]'''. The implementation of this interface is different for each platform. It may even be different for different APZCs within one platform (for example, in the B2G browser, APZCs representing scrollable elements in content processes use the RemoteContentController implementation, while those representing scrollable elements in the parent process will use a different implementation (currently being developed in {{bug|912657}})). | |||
GeckoContentController allows the APZ to do the following: | GeckoContentController allows the APZ to do the following: |
Revision as of 19:50, 4 November 2013
Introduction
The Async Pan/Zoom module (APZ)1 is a platform component that allows panning and zooming to be performed asynchronously (on the compositor thread rather than the main thead).
For zooming, this means that the APZ reacts to a pinch gesture immediately and instructs the compositor to scale the already-rendered layers at whatever resolution they have been rendered (so e.g. text becomes more blurry as you zoom in), and meanwhile sends a request to Gecko to re-render the content at a new resolution (with sharp text and all).
For panning, this means that the APZ asks Gecko to render a portion of a scrollable layer, called the "display port", that's larger than the visible portion. It then reacts to a pan gesture immediately, asking the compositor to render a different portion of the displayport (or, if the displayport is not large enough to cover the new visible region, then nothing in the portions it doesn't cover - this is called checkerboarding), and meanwhile sends a request to Gecko to render a new displayport. (The displayport can also be used when zooming out causes more content of a scrollable layer to be shown than before.)
1. This module used to be called Async Pan/Zoom Controller (APZC), but this was changed to avoid confusion because there is a class called AsyncPanZoomController of which there are now multiple instances.
Supported platforms
The APZ module is currently enabled on B2G and Metro. Fennec has a Java implementation of asynchronous panning and zooming, but the plan is to port Fennec to use the APZ module as well.
The APZ module relies on OMTC, so a prerequisite for porting it to a platform is for OMTC to work on that platform.
AsyncPanZoomControllers
Inside the APZ module, every scrollable layer has an AsyncPanZoomController (APZC). Scrollable layers roughly correspond to the root document, documents in iframes, and overflow:scroll elements. See OMTC for more information about layers.
The APZCs are arranged in a tree whose structure reflects the structure of the layer tree containing the layers that they correspond to, except that the APZC tree only has nodes for scrollable layers, while the layer tree has nodes for all layers. The APZC tree is managed by a class called APZCTreeManager. The APZCTreeManager is the interface through which the outside world interacts with the APZ module - there is no access to the APZCs directly, but the APZCTreeManager provides methods that operate on a specific APZC in the tree. These methods identify an APZC using three integer identifiers, grouped in a structure called ScrollableLayerGuid. The three identifiers are:
- A layers id, which identifies the layer tree that the scrollable layer belongs to. Layers ids are maintained by the compositor, with CompositorParent::RootLayerTreeId() returning the layers id for the root layer tree, and CompositorParent::AllocateLayerTreeId() allocating a layers id for a new layer tree.
- A pres shell id, which is a temporal identifier that correponds to the document that contains the scrollable layer, which may change over time. The pres shell id can be obtained using nsIDOMWindowUtils::GetPresShellId().
- A scroll id, which identifies the actual scroll frame. The scroll id is called a view id in Gecko code, and can be obtained using nsIDOMWindowUtils::GetViewId().
Interactions with other components
The APZ interacts with the following other platform components:
Compositor
The compositor creates and stores the APZCTreeManager, and interacts with it in the following ways:
- When the compositor receives an update to the layer tree, it propagates this update to the APZCTreeManager by calling APZCTreeManager::UpdatePanZoomControllerTree(). This function updates the tree of APZCs to reflect the tree of scrollable layers in the updated layer tree.
- Every time the compositor composites a frame, it queries each APZC for its current async transform (see AsyncPanZoomController::SampleContentTransformForFrame()). The APZC modifies this transform as the user pans and zooms.
- APZCs can schedule a composite by calling CompositorParent::ScheduleRenderOnCompositorThread().
Widget code
The widget code is a platform-specific component of a browser implementation that interfaces with the native widget implementation. It corresponds roughly to the following pieces of code:
- On B2G: RenderFrameParent/RenderFrameChild and TabParent/TabChild
- On Metro: MetroWidget and MetroInput
- On Fennec (which doesn't use the APZ yet): GeckoAppShell and GeckoLayerClient, which communicate with native code via AndroidJNI.
The widget code interacts with the APZ in the following ways:
- forwards relevant input events to the APZ (APZCTreeManager::ReceiveInputEvent())
- notifies the APZ about Gecko events that are relevant to it, such as:
- a reflow that causes a change in the dimensions of a scrollable layer (APZCTreeManager::UpdateCompositionBounds())
- a scrollTo performed by content (APZCTreeManager::UpdateScrollOffset())
- a request to zoom in to a rectangle (APZCTreeManager::ZoomToRect())
In addition, the widget code provides APZ with an interface for interacting with Gecko, called GeckoContentController. The implementation of this interface is different for each platform. It may even be different for different APZCs within one platform (for example, in the B2G browser, APZCs representing scrollable elements in content processes use the RemoteContentController implementation, while those representing scrollable elements in the parent process will use a different implementation (currently being developed in bug 912657)).
GeckoContentController allows the APZ to do the following:
- request a repaint (GeckoContentController::RequestContentRepaint())
- request handling of various gestures, such as single taps, double taps, and long taps (GeckoContentController::HandleSingleTap() etc.)
- fire async scroll events (GeckoContentController::SendAsyncScrollDOMEvent())
- schedule arbitrary actions to be performed on the Gecko thread (GeckoContentController::PostDelayedTask())
Threads and processes
When OMTC is enabled on a platform (which is a requirement for using the APZC), the compositor runs on its own thread, called the compositor thread. APZCs and the APZCTreeManager can be thought of as living on the compositor thread, although they can be used in certain ways by other threads (usually the Gecko thread, or the platform UI thread if there is one). APZCTreeManager.h documents which APZCTreeManager methods can be called on which threads.
On B2G, there are not only multiple threads but also multiple processes, as each app (or in the case of the browser, each tab) has its own process. In this setup, only the parent process has a compositor thread, and all APZCs live in the parent process, even ones corresponding to layers from a child thread.
Main APZ projects on the horizon
- Make APZ work well for Metro - bug 886321
- Implement support for Fennec-like dynamic toolbar on B2G - bug 860812
- Improve hit detection for the different touch-sensitive regions - bug 928833
- Turn on APZ in all Gaia apps - bug 909877
- Switch Fennec over from the Java version to the C++ APZ - bug 776030
FAQ
If you have questions about anything APZ-related, please add them here, and somebody watching this page will try to answer it.
- What platforms is APZ currently enabled on? [2013-10-28]
- APZ is currently enabled in the B2G (browser content only) and on Firefox Metro (when running in metro mode).