Overview
SurfaceFlinger is the central display compositor in Android. It accepts buffers from multiple applications and system services, composites them based on their Z-order and properties, and sends the final output to the display via the Hardware Composer (HWC).
SurfaceFlinger as Display Compositor
Every visible application in Android renders its UI into a graphic buffer. SurfaceFlinger acts as the traffic controller, collecting these buffers, determining how they overlap, applying transformations (such as rotation or scaling), and deciding whether the GPU or the HWC should perform the final composition.
SurfaceFlinger operates in its own dedicated process and interacts closely with the WindowManagerService (WMS). While WMS manages the logical window state (bounds, visibility, z-order), SurfaceFlinger manages the physical buffers and their presentation.
Layer Management and Z-Ordering
SurfaceFlinger manages visual elements as "Layers". Each Layer corresponds to a surface from an application or a system element (like the status bar or navigation bar).
// A simplified view of Layer in SurfaceFlinger
class Layer : public virtual RefBase {
public:
virtual void onDraw(const RenderArea& renderArea, const Region& clip) const = 0;
virtual void setZOrder(uint32_t z);
virtual void setPosition(float x, float y);
// ...
private:
uint32_t mZOrder;
Rect mBounds;
sp<GraphicBuffer> mActiveBuffer;
};
Z-ordering dictates the stacking order of these layers. The WindowManagerService computes the correct Z-order based on the window hierarchy and pushes this state to SurfaceFlinger using IPC.
Client Surface Creation (SurfaceSession)
When an application starts, it requests a window from WindowManagerService. Behind the scenes, a connection to SurfaceFlinger is established via a SurfaceSession.
- The app requests a surface via
WindowManagerService. - WMS communicates with SurfaceFlinger to create a
Layer. - SurfaceFlinger returns an
IGraphicBufferProducerinterface. - The application wraps this in a
Surfaceobject to draw into it.
// Java layer wrapper for a Surface control
SurfaceControl surfaceControl = new SurfaceControl.Builder(session)
.setName("MyAppSurface")
.setBufferSize(width, height)
.setFormat(PixelFormat.RGBA_8888)
.build();
SurfaceFlinger Composition Modes
SurfaceFlinger relies on the Hardware Composer (HWC) to determine the most efficient way to composite layers. Before every frame, SurfaceFlinger prepares a list of layers and asks the HWC how it can handle them.
The two primary paths are:
- Device Composition: The display hardware overlays the buffers directly. This is highly efficient and consumes less power.
- Client Composition: The HWC cannot handle the layers (due to hardware limits like the number of overlay planes). SurfaceFlinger uses the GPU (via OpenGL ES or Vulkan) to composite these layers into a single "scratch" buffer, which is then sent to the display.
Composition Types
The HWC categorizes layers into specific composition types:
- Client: The layer must be composited by the GPU. SurfaceFlinger draws this layer into a target buffer.
- Device: The layer will be handled entirely by the HWC hardware overlay. SurfaceFlinger simply passes the buffer handle to the HWC.
- Solid Color: The layer has no buffer but is filled with a solid color. The HWC hardware fills the region.
- Cursor: A special overlay dedicated to a hardware mouse cursor, minimizing latency.
Debugging SurfaceFlinger
To view the current layer hierarchy, Z-orders, and composition types, use the dumpsys command:
adb shell dumpsys SurfaceFlinger
This output will detail the exact buffer formats, active layers, and whether the frame was composed via Device or Client composition.