Platform/GFX/APZ: Difference between revisions

(→‎Widget code: The Fennec Java files have been moved to a separate java directory.)
 
(5 intermediate revisions by the same user not shown)
Line 11: Line 11:
== Supported platforms ==
== 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 is enabled on Fennec as of version 48. It is also enabled on desktop as of version 48 if e10s is enabled. The easiest way to check if it is enabled is by going to about:support and checking the "Asynchronous Pan/Zoom" line in the Graphics section.


The APZ module relies on [[Platform/GFX/OffMainThreadCompositing|OMTC]], so a prerequisite for porting it to a platform is for OMTC to work on that platform.
The APZ module relies on [[Platform/GFX/OffMainThreadCompositing|OMTC]], so a prerequisite for porting it to a platform is for OMTC to work on that platform.
Line 34: Line 34:


* 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.
* 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.
* Every time the compositor composites a frame, it queries each APZC for its current async transform (see AsyncPanZoomController::GetCurrentAsyncTransform()). The APZC modifies this transform as the user pans and zooms.
* APZCs can schedule a composite by calling CompositorParent::ScheduleRenderOnCompositorThread().
* APZCs can schedule a composite (for the next frame of a scroll animation, for instance) by calling CompositorParent::ScheduleRenderOnCompositorThread().


=== Widget code ===
=== 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:
The '''widget code''' is a platform-specific component of a browser implementation that interfaces with the native widget implementation. The widget code interacts with the APZ in the following ways:
* On B2G: [http://dxr.mozilla.org/mozilla-central/source/layout/ipc/RenderFrameParent.h RenderFrameParent]/[http://dxr.mozilla.org/mozilla-central/source/layout/ipc/RenderFrameChild.h RenderFrameChild] and [http://dxr.mozilla.org/mozilla-central/source/dom/ipc/TabParent.h TabParent]/[http://dxr.mozilla.org/mozilla-central/source/dom/ipc/TabChild.h TabChild]
* On Metro: [http://dxr.mozilla.org/mozilla-central/source/widget/windows/winrt/MetroWidget.h MetroWidget] and [http://dxr.mozilla.org/mozilla-central/source/widget/windows/winrt/MetroInput.h MetroInput]
* On Fennec (which doesn't use the APZ yet): [https://dxr.mozilla.org/mozilla-central/source/mobile/android/base/java/org/mozilla/gecko/GeckoAppShell.java GeckoAppShell] and [https://dxr.mozilla.org/mozilla-central/source/mobile/android/base/java/org/mozilla/gecko/gfx/GeckoLayerClient.java GeckoLayerClient], which communicate with native code via [http://dxr.mozilla.org/mozilla-central/source/widget/android/AndroidJNI.cpp AndroidJNI].
 
The widget code interacts with the APZ in the following ways:


* forwards relevant input events to the APZ (APZCTreeManager::ReceiveInputEvent())
* forwards relevant input events to the APZ (APZCTreeManager::ReceiveInputEvent())
* notifies the APZ about Gecko events that are relevant to it, such as:
* 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())
** how content responded to an input event (APZCTreeManager::ContentReceivedInputBlock())
** a scrollTo performed by content (APZCTreeManager::UpdateScrollOffset())
** a change in the zoom constraints (APZCTreeManager::UpdateZoomConstraints())
** 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 '''[http://dxr.mozilla.org/mozilla-central/source/gfx/layers/apz/public/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}})).
In addition, the widget code provides APZ with an interface for interacting with Gecko, called '''[http://dxr.mozilla.org/mozilla-central/source/gfx/layers/apz/public/GeckoContentController.h GeckoContentController]'''. The implementation of this interface is different for different platforms. It may even be different for different APZCs within one platform, depending on which process the controller lives in.


GeckoContentController allows the APZ to do the following:
GeckoContentController allows the APZ to do the following:


* request a repaint (GeckoContentController::RequestContentRepaint())
* request a repaint (GeckoContentController::RequestContentRepaint())
* request handling of various gestures, such as single taps, double taps, and long taps (GeckoContentController::HandleSingleTap() etc.)
* request handling of various gestures, such as single taps, double taps, and long taps (GeckoContentController::HandleTap() etc.)
* fire async scroll events (GeckoContentController::SendAsyncScrollDOMEvent())
* fire state change notifications (GeckoContentController::NotifyAPZStateChange())
* schedule arbitrary actions to be performed on the Gecko thread (GeckoContentController::PostDelayedTask())
* schedule arbitrary actions to be performed with a delay (GeckoContentController::PostDelayedTask())


== Threads and processes ==
== Threads and processes ==
Line 65: Line 60:
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). [http://dxr.mozilla.org/mozilla-central/source/gfx/layers/apz/src/APZCTreeManager.h APZCTreeManager.h] documents which APZCTreeManager methods can be called on which threads.
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). [http://dxr.mozilla.org/mozilla-central/source/gfx/layers/apz/src/APZCTreeManager.h 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.
On some platforms there are not only multiple threads but also multiple processes. In this setup, the compositor lives in the GPU process (if there is one - currently Windows only), or the UI process otherwise. All the APZCs live in the same process as the compositor, even ones corresponding to layers from a content process.


== Coordinate systems ==
== Coordinate systems ==
Line 73: Line 68:
* [https://staktrace.com/spout/entry.php?id=800 Unraveling coordinate systems]
* [https://staktrace.com/spout/entry.php?id=800 Unraveling coordinate systems]
* [https://staktrace.com/spout/entry.php?id=801 Unraveling coordinate systems, part 2]
* [https://staktrace.com/spout/entry.php?id=801 Unraveling coordinate systems, part 2]
* [http://dxr.mozilla.org/mozilla-central/source/gfx/layers/apz/src/APZCTreeManager.cpp#1052 The comment above APZCTreeManager::GetInputTransforms()]
* [https://searchfox.org/mozilla-central/rev/6f86cc3479f80ace97f62634e2c82a483d1ede40/gfx/layers/apz/src/APZCTreeManager.cpp#2795 The comment above APZCTreeManager::GetScreenToAPZCTransform()]
* [https://bug935219.bugzilla.mozilla.org/attachment.cgi?id=8380975 Diagram illustrating the coordinate confusion that gave rise to bug 935219]
* [https://bug935219.bugzilla.mozilla.org/attachment.cgi?id=8380975 Diagram illustrating the coordinate confusion that gave rise to bug 935219]


Line 81: Line 76:


This logging can be turned on by setting the "apz.printtree" pref to "true".
This logging can be turned on by setting the "apz.printtree" pref to "true".
Additional logging can be enabled by looking for *_LOG macros at the top of .cpp files, and setting the MOZ_LOG environment variable appropriately. For example, setting <tt>MOZ_LOG=apz.inputqueue:4</tt> is often useful for tracing input events through the APZ code.


== Main APZ-related projects on the horizon ==
== Main APZ-related projects on the horizon ==


See [https://etherpad.mozilla.org/apz-planning the APZ planning etherpad].
See [https://github.com/orgs/FirefoxGraphics/projects/7 the APZ planning GitHub project].


== FAQ ==
== FAQ ==
Line 90: Line 87:
If you have questions about anything APZ-related, please add them here, and somebody watching this page will try to answer it.
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? [2014-01-14] : As of January 8, 2014, APZ is currently enabled in all B2G processes that are not the root process (i.e. this includes all browser content and Gaia apps). It is also enabled on Firefox Metro (when running in metro mode).
; What platforms is APZ currently enabled on? [2016-09-13] : APZ is currently enabled in all B2G processes, Firefox desktop with e10s enabled, and Fennec.


; How does APZ impact the onload event? Will this impact user perceived performance? [2014-01-28] : In general APZ shouldn't really impact the onload event. We might be painting a larger area now but if the app is well-behaved and doesn't trigger a lot of paints the impact from this should not be very large. If there are reports of delayed onload because of APZ, it would be useful to get profiles with and without APZ enabled to compare.
; How does APZ impact the onload event? Will this impact user perceived performance? [2014-01-28] : In general APZ shouldn't really impact the onload event. We might be painting a larger area now but if the app is well-behaved and doesn't trigger a lot of paints the impact from this should not be very large. If there are reports of delayed onload because of APZ, it would be useful to get profiles with and without APZ enabled to compare.
Line 102: Line 99:
== Where to go for more answers ==
== Where to go for more answers ==


APZ now has its own IRC channel, #apz. You can also try #gfx and #developers. Ping kats, botond, tn, BenWa or Cwiiis.
APZ now has its own matrix channel, #apz:mozilla.org. You can also try #gfx:mozilla.org and #developers:mozilla.org. Ping kats, botond, mstange, or tnikkel.
Confirmed users
586

edits