Overview
The Hardware Composer (HWC) is an abstraction layer that allows SurfaceFlinger to offload the composition of graphic layers to the display hardware. By utilizing hardware overlay planes, HWC bypasses the GPU, significantly reducing power consumption and memory bandwidth.
HWC HAL Interface
The HWC Hardware Abstraction Layer (HAL) defines the interface between SurfaceFlinger and the vendor-specific display drivers. Vendors implement the HWC HAL to map Android's composition requests to their specific SoC's display controller capabilities.
// Example HAL API interaction (simplified)
hwc2_device_t* hwcDevice;
// ... initialization ...
hwcDevice->presentDisplay(hwcDevice, displayId, &presentFence);
SurfaceFlinger acts as the client to the HWC HAL, constantly feeding it lists of layers for every frame.
HWC Layer Validation and Presentation
The composition process follows a strict "prepare and set" cycle (or "validate and present" in modern HWC implementations).
- Validation (Prepare): SurfaceFlinger sends all visible layers to the HWC and asks, "How can you compose this?" The HWC evaluates its hardware constraints (e.g., maximum supported overlays, scaling limits) and assigns a composition type to each layer.
- Presentation (Set): SurfaceFlinger accepts the HWC's decisions. For layers marked as
Device, SurfaceFlinger does nothing. For layers marked asClient, SurfaceFlinger uses the GPU to composite them into a target buffer. Finally, SurfaceFlinger tells the HWC to present the frame to the display.
GPU Fallback Composition
Hardware overlays are limited. An SoC might only support 3 or 4 concurrent hardware layers. If there are 10 visible layers on screen (e.g., status bar, navigation bar, app background, floating windows), the HWC cannot handle them all natively.
When this happens, the HWC assigns the Client composition type to the excess layers. SurfaceFlinger falls back to using OpenGL ES or Vulkan to draw these layers into a single framebuffer. This framebuffer is then handed to the HWC as a standard Device layer. This process is known as GPU Fallback Composition.
HWC2 vs HWC3
The HWC API has evolved over time:
- HWC1: The legacy API, strictly synchronous and less flexible regarding hotplugging and multi-display setups.
- HWC2: Introduced in Android 7.0 (Nougat). It brought a cleaner, object-oriented model separating Displays, Layers, and Configuration. It formalized the Validate and Present phases.
- HWC3 / AIDL HAL: Android 13 introduced an AIDL-based HWC interface, moving away from HIDL. This modernizes the IPC mechanism and allows for better updatability and stricter typing.
Display Capabilities Query
SurfaceFlinger queries the HWC to understand the display's capabilities upon boot or display hotplug. This includes:
- Supported Resolutions and Refresh Rates: Important for variable refresh rate (VRR) and mode switching.
- Color Gamut and HDR Support: Determining if the display supports DCI-P3 or HDR10.
- Protected Content: Checking if the display can securely handle DRM-protected buffers.
To see the current HWC capabilities and active layers, use:
adb shell dumpsys SurfaceFlinger --hwc
This command provides a low-level dump of the HWC state, showing exactly how many hardware planes are currently active.