VSYNC

The VSYNC signal synchronizes the display pipeline. The display
pipeline consists of app rendering, SurfaceFlinger composition, and the Hardware
Composer (HWC) presenting images on the display. VYSNC synchronizes the
time apps wake up to start rendering, the time SurfaceFlinger wakes up to
composite the screen, and the display refresh cycle. This synchronization
eliminates stutter and improves the visual performance of graphics.

The HWC generates VSYNC events and sends the events to SurfaceFlinger through
the callback:

Note: The HWC triggers
hwc2_callback_data_t from a thread of
HAL_PRIORITY_URGENT_DISPLAY with as little latency as possible,
typically less than 0.5 ms.

SurfaceFlinger controls whether or not the HWC generates VSYNC events by
calling to setVsyncEnabled. SurfaceFlinger enables
setVsyncEnabled to generate VSYNC events so it can synchronize with
the refresh cycle of the display. When SurfaceFlinger is synchronized to the
display refresh cycle, SurfaceFlinger disables setVsyncEnabled to
stop the HWC from generating VSYNC events. If SurfaceFlinger detects a
difference between the actual VSYNC and the VSYNC it previously established
SurfaceFlinger re-enables VSYNC event generation.

Synchronizing with VSYNC delivers consistent latency. It reduces errors in
apps and SurfaceFlinger and minimizes displays drifting in and out of phase with
each other. This, assumes app and SurfaceFlinger per-frame
times don’t vary widely. The latency is at least two frames.

To remedy this, you can employ VSYNC offsets to reduce the input-to-display
latency by making app and composition signal relative to hardware
VSYNC. This is possible because app plus composition usually takes less
than 33 ms.

The result of VSYNC offset is three signals with same period and offset
phase:

HW_VSYNC_0 — Display begins showing next frame.

VSYNC — App reads input and generates next frame.

SF_VSYNC — SurfaceFlinger begins compositing for next frame.

With VSYNC offset, SurfaceFlinger receives the buffer and composites the
frame while the app simultaneously processes the input and renders
the frame.

Note: VSYNC offsets reduce the time available
for app and composition, providing a greater chance for error.

DispSync

DispSync maintains a model of the periodic hardware-based VSYNC events of a
display and uses that model to execute callbacks at specific phase
offsets from the hardware VSYNC events.

DispSync is a software phase-lock loop (PLL) that generates the
VSYNC and SF_VSYNC signals used by Choreographer and SurfaceFlinger, even if
not offset from hardware VSYNC.

Figure 1. DispSync flow

DispSync has the following qualities:

Reference — HW_VSYNC_0.

Output — VSYNC and SF_VSYNC.

Feedback — Retire fence signal timestamps from Hardware Composer.

VSYNC/Retire offset

The signal timestamp of retire fences must match HW VSYNC, even on devices
that don’t use the offset phase. Otherwise, errors appear to be more severe
than they are. Smart panels often have a delta where the retire fence is the end
of direct memory access (DMA) to display memory, but the actual display switch
and HW VSYNC is some time later.

PRESENT_TIME_OFFSET_FROM_VSYNC_NS is set in the device’s
BoardConfig.mk makefile. It's based on the display controller and panel
characteristics. The time from the retire fence timestamp to the HW VSYNC
signal is measured in nanoseconds.

VSYNC and SF_VSYNC offsets

VSYNC_EVENT_PHASE_OFFSET_NS and
SF_VSYNC_EVENT_PHASE_OFFSET_NS are set conservatively based on
high-load use cases, such as partial GPU composition during window transition
or Chrome scrolling through a web page containing animations. These offsets
allow for long app render time and long GPU composition time.

More than a millisecond or two of latency is noticeable. To minimize latency
without significantly increasing error counts, integrate thorogh automated error
testing.

Note: VSYNC and SF_VSYNC offsets are also
configured in the device’s BoardConfig.mk file. Both settings are
offset in nanoseconds after HW_VSYNC_0, default to zero (if not set),
and can be negative.

Content and code samples on this page are subject to the licenses described in the Content License. Java is a registered trademark of Oracle and/or its affiliates.