Unsignaled buffer latching with AutoSingleLayer

Android 13 adds a new configuration called AutoSingleLayer for latching unsignaled buffers. This configuration lets SurfaceFlinger latch an unsignaled buffer when only a single layer is updating, and not for the cases that occur across layers, such as geometry changes or sync transactions.

Before Android 13, the debug.sf.latch_unsignaled flag in AOSP lets SurfaceFlinger latch all unsignaled buffers, regardless of the use case. When this configuration is enabled, there are undesired side effects, such as breaking sync transactions and freezing the entire display while waiting on incomplete buffers.

With the AutoSingleLayer mode, only a buffer of a single surface is updated in a frame. This mode enables games and other fullscreen apps to get the benefit of latching unsignaled buffers and reducing app jank while remaining unaffected by display freezes.

AutoSingleLayer mode settings

In Android 13, AutoSingleLayer is the default mode for the latch unsignaled buffer feature. This mode is controlled by the system property debug.sf.auto_latch_unsignaled.

SurfaceFlinger reads LatchUnsignaledConfig on boot. Here are the possible configurations:

  • LatchUnsignaledConfig::AutoSingleLayer

    In this AOSP default mode, latching unsignaled buffers is permitted when a single layer is updated in a frame, and the update includes just a buffer update with no sync transactions or geometry changes. In this mode, debug.sf.auto_latch_unsignaled is set to true by default.

  • LatchUnsignaledConfig::Disabled

    This mode disables the latch unsignaled behavior and latches only signaled transactions. This mode also disables the AutoSingleLayer mode. To configure this mode, set debug.sf.latch_unsignaled and debug.sf.auto_latch_unsignaled to false.

  • LatchUnsignaledConfig::Always

    In this mode, all buffers are latched unsignaled. To configure this mode, set debug.sf.latch_unsignaled to true.

Test AutoSingleLayer

To test whether a buffer is latched unsignaled, look for the following traces from SurfaceFlinger in Perfetto:

Trace of latched unsignaled buffer

Figure 1. Trace of a latched unsignaled buffer in Perfetto