SurfaceFlinger and WindowManager

SurfaceFlinger accepts, composes, and sends buffers to the display. WindowManager provides SurfaceFlinger with buffers and window metadata, which SurfaceFlinger then uses to composite surfaces to the display.

SurfaceFlinger

SurfaceFlinger can accept buffers in two ways: through BufferQueue and SurfaceControl, or through ASurfaceControl.

One way SurfaceFlinger accepts buffers is through BufferQueue and SurfaceControl. When an app comes to the foreground, it requests buffers from WindowManager. WindowManager then requests a layer from SurfaceFlinger. A layer is a combination of a surface, which contains the BufferQueue, and a SurfaceControl instance, which contains the layer metadata like the display frame. SurfaceFlinger creates the layer and sends it to WindowManager. WindowManager then sends the surface to the app, but keeps the SurfaceControl instance to manipulate the appearance of the app on the screen.

Starting with Android 10, ASurfaceControl provides another way for SurfaceFlinger to accept buffers. ASurfaceControl combines a surface and a SurfaceControl instance into one transaction package that SurfaceFlinger receives. ASurfaceControl is associated with a layer, which apps update through ASurfaceTransaction instances. Apps then get information about ASurfaceTransaction instances through callbacks that pass ASurfaceTransactionStats containing information, such as latch time, acquire times, for example.

The following table describes ASurfaceControl and its associated components:

Component Description
ASurfaceControl Wraps SurfaceControl and lets an app create SurfaceControl instances that correspond to layers on the display.
Can be created as a child of ANativeWindow or as a child of another ASurfaceControl instance.
ASurfaceTransaction Wraps Transaction to let the client edit a layer's descriptive properties, such as geometry, and sends the updated buffers to SurfaceFlinger.
ASurfaceTransactionStats Sends information about transactions that have been presented, such as latch time, acquire times, and previous release fence, to an app through a preregistered callback.

Though apps can submit buffers at any time, SurfaceFlinger only wakes up to accept buffers between display refreshes, which can differ depending on the device. This minimizes memory usage and avoids visible tearing on the screen, which can occur when updating the display mid-refresh.

When the display is between refreshes, the display sends the VSync signal to SurfaceFlinger. The VSync signal indicates that it can refresh the display without tearing. When SurfaceFlinger receives the VSync signal, it walks through its list of layers looking for new buffers. If it finds a new buffer, SurfaceFlinger acquires the buffer; if not, it continues to use the previously acquired buffer. SurfaceFlinger must always display something, so it hangs on to one buffer. If no buffers have ever been submitted on a layer, SurfaceFlinger ignores the layer.

After SurfaceFlinger has collected all buffers for visible layers, it asks the Hardware Composer (HWC) how it should perform composition. If the HWC marks layer composition type as client composition, SurfaceFlinger composites those layers. Then, SurfaceFlinger passes the output buffer to the HWC.

WindowManager

WindowManager controls Window objects, which are containers for View objects. Window objects are always backed by Surface objects. WindowManager oversees lifecycles, input and focus events, screen orientation, transitions, animations, position, transforms, z-order, and many other aspects of a window. WindowManager sends all of the window metadata to SurfaceFlinger so SurfaceFlinger can use that data to composite surfaces on the display.

Pre-rotation

Many hardware overlays don't support rotation (and even if they do, it costs processing power); the solution is to transform the buffer before it reaches SurfaceFlinger. Android supports a query hint (NATIVE_WINDOW_TRANSFORM_HINT) in ANativeWindow to represent the most likely transform that SurfaceFlinger will apply to the buffer. GL drivers can use this hint to pre-transform the buffer before it reaches SurfaceFlinger so that when the buffer arrives, it's correctly transformed.

For example, when receiving a hint to rotate 90 degrees, generate and apply a matrix to the buffer to prevent it from running off the end of the page. To save power, do this pre-rotation. For details, see the ANativeWindow interface defined in system/core/include/system/window.h.