Advanced AOSP Subsystems
3 min read

SurfaceFlinger

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.

  1. The app requests a surface via WindowManagerService.
  2. WMS communicates with SurfaceFlinger to create a Layer.
  3. SurfaceFlinger returns an IGraphicBufferProducer interface.
  4. The application wraps this in a Surface object 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.