Implementing Virtual Displays

Android added platform support for virtual displays in Hardware Composer v1.3 (support can be used by Miracast). The virtual display composition is similar to the physical display: Input layers are described in prepare(), SurfaceFlinger conducts GPU composition, and layers and GPU framebuffer are provided to Hardware Composer in set().

Instead of the output going to the screen, it is sent to a gralloc buffer. Hardware Composer writes output to a buffer and provides the completion fence. The buffer is sent to an arbitrary consumer: video encoder, GPU, CPU, etc. Virtual displays can use 2D/blitter or overlays if the display pipeline can write to memory.


Each frame is in one of three modes after prepare():

  • GLES. All layers composited by GPU, which writes directly to the output buffer while Hardware Composer does nothing. This is equivalent to virtual display composition with Hardware Composer version older than v1.3.
  • MIXED. GPU composites some layers to framebuffer, and Hardware Composer composites framebuffer and remaining layers. GPU writes to scratch buffer (framebuffer); Hardware Composer reads scratch buffer and writes to the output buffer. Buffers may have different formats, e.g. RGBA and YCbCr.
  • HWC. All layers composited by Hardware Composer, which writes directly to the output buffer.

Output format

Output format depends on the mode:

  • MIXED and HWC modes. If the consumer needs CPU access, the consumer chooses the format. Otherwise, the format is IMPLEMENTATION_DEFINED. Gralloc can choose best format based on usage flags. For example, choose a YCbCr format if the consumer is video encoder, and Hardware Composer can write the format efficiently.
  • GLES mode. EGL driver chooses output buffer format in dequeueBuffer(), typically RGBA8888. The consumer must be able to accept this format.

EGL requirement

Hardware Composer v1.3 virtual displays require that eglSwapBuffers() does not dequeue the next buffer immediately. Instead, it should defer dequeueing the buffer until rendering begins. Otherwise, EGL always owns the next output buffer. SurfaceFlinger can’t get the output buffer for Hardware Composer in MIXED/HWC mode.

If Hardware Composer always sends all virtual display layers to GPU, all frames will be in GLES mode. Although not recommended, you may use this method if you need to support Hardware Composer v1.3 for some other reason but can’t conduct virtual display composition.