Android 11 adds support for devices with multiple refresh rates. There are three main components to this feature:
- New HAL APIs introduced in
- Platform code to parse device configs for different refresh rates and set the desired refresh rate
- New SDK and NDK APIs to allow apps to set their desired frame rate
Dedicated support for refresh rate switching has been added to
We strongly recommend using this version since previous versions of
composer HAL have limited support for refresh rate switching.
A new attribute
CONFIG_GROUP was added to
IComposerClient::Attribute that is queryable using the
getDisplayAttribute_2_4 API. This attribute allows vendors to group
together display configurations. Configurations in the same group allows
seamless switching between them in most of the cases. The config group is used
by the platform to differentiate which configurations can be switched between
them in order to switch the refresh rate and not other attributes for a
Consider the following example that demonstrates the benefits of using config groups with a device that supports four display configurations:
Even though the device supports 48Hz, 60Hz, 72Hz, and 90Hz refresh rates the display operates at a different mode and switching from 60Hz to 72Hz changes the display config from 1080p to 1080i, which might not be the desired behavior. This is solved by using config groups. By grouping 60Hz and 90Hz together in one config group and 48Hz and 72Hz in another config group. The platform knows that it can switch between 60Hz and 90Hz and between 48Hz and 72Hz but not between 60Hz and 72Hz as this will result in a config change rather than simply changing the refresh rate.
Composer API updates
- For better control and predictability when changing refresh rates
getDisplayVsyncPeriodhas been added.
getDisplayVsyncPeriodreturns the current refresh rate (in terms of vsync period) the display operates at. This is especially useful while transitioning between refresh rate and the current refresh rate is needed by the platform to decide when to start the next frame.
setActiveConfigWithConstraintsmethod is a new extension to the existing
setActiveConfigmethod and provides more information about the config change. The constraints are given as part of the
vsyncPeriodChangeConstraintsparameters and contain the following parameters.
- The time in
CLOCK_MONOTONICafter which the vsync period may change (that is the vsync period must not change before this time). This is useful when the platform wants to plan ahead for a refresh rate change but it already has some buffers in the queue to present. The platform sets this time accordingly to account for those buffers and make sure that the refresh rate transition will be as smooth as possible.
- If true, requires that the vsync period change must happen seamlessly
without a noticeable visual artifact. This flag is used by the platform when a
refresh rate change is needed as a result of a content change (for example, the
device is idle and animation starts). This gives the vendor the opportunity to
not allow certain configuration changes when they might result in a noticeable
visual artifact. If the configs can't be changed seamlessly and
seamlessRequiredis set to
true, the implementation is expected to return
SEAMLESS_NOT_POSSIBLEas the return code and call the new
onSeamlessPossiblecallback when the same config change can be done seamlessly.
Upon success the implementation returns a
VsyncPeriodChangeTimelinewhich tells the platform when to expect the refresh rate change to occur.
newVsyncAppliedTimeNanosparameters need to be set to the time in
CLOCK_MONOTONICwhen the new display will start to refresh at the new vsync period. This, together with
desiredTimeNanosallows the platform to plan in advance the refresh rate switch and start ticking apps for the new refresh rate in advance. This allows a seamless transition of the refresh rate.
Some implementations require a refresh frame to be sent before the refresh rate can be sent. For that, the HAL has the
refreshRequiredparameter to indicate that a refresh frame is needed and
refreshTimeNanosto indicate the first vsync where a refresh frame needs to be sent after.
- onVsyncPeriodTimingChanged [callback]
- A new callback that can be called by the HAL to indicate to the platform that some parameter of the timeline changed and the platform needs to adjust its timeline. This callback is expected to be called if for some reason the old timeline was missed because of a long processing time on the HAL or a late refresh frame.
How does the platform decide to change the refresh rate?
The refresh rate selection happens in the following two system services:
DisplayManagersets the high level policy around the refresh rate. It sets a default display config, which is the same as the composer HAL config. Additionally, it sets a range of minimum and maximum values for
SurfaceFlingerto choose as the refresh rate.
- Determines the refresh rate by setting a config which is in the same config group as the default config and with a refresh rate within the min/max range.
The Display Manager runs through the following steps to determine the policy:
- Finds the default config ID by querying the active config from
- Restricting the range of minimum and maximum values by iterating over the
- Default refresh rate setting: The default refresh rate value
is set in the
R.integer.config_defaultRefreshRateconfig overlay. This value is used to determine the standard device refresh rate for animations and touch interactions.
- Peak refresh rate setting: The peak refresh rate value
is read from
Settings.System.PEAK_REFRESH_RATE. This value is changed in runtime to reflect the current device setting (such as from a menu option). The default value is set in the
- Minimum refresh rate setting: The minimum refresh rate
value is read from
Settings.System.MIN_REFRESH_RATE. This value can be changed in runtime to reflect the current device setting (such as from a menu option). The default value is 0, so there is no default minimum.
- Application requested ModeId: Apps can set
WindowManager.LayoutParams.preferredDisplayModeIdto reflect a preferred config the display should operate at. In most conditions the
DisplayManagersets the default config ID accordingly and sets the minimum and maximum refresh rate to match the config's refresh rate.
- Battery Saver: The refresh rate is restricted to 60Hz or
lower when the device is in low power mode, which is indicated through
- Default refresh rate setting: The default refresh rate value is set in the
DisplayManager sets the policy,
SurfaceFlinger sets the refresh rate based on the active layers (layers that queue
frame updates). If the owner of the layer sets a frame rate, SurfaceFlinger
tries to set the refresh rate to something that is a multiplier of that rate.
For example if two active layers set their frame rate to 24 and 60 SurfaceFlinger
will pick 120Hz if it is available. If such refresh rate is not available to
SurfaceFlinger, it will try to pick the refresh rate which has the minimal
error for the frame rate. For more information see the developer documentation on developer.android.com
SurfaceFlinger maintains the following flags to
control how the refresh rate is decided:
ro.surface_flinger.use_content_detection_for_refresh_rate:If set the refresh rate is decided based on the active layers, even if a frame rate was not set. SurfaceFlinger maintains a heuristic where it finds the average fps the layer is posting buffers by looking at the presentation timestamp attached to the buffer.
ro.surface_flinger.set_touch_timer_ms: if > 0, the default refresh rate will be used when a user touches the screen for the configured timeout. This heuristic is done to be ready with the default refresh rate for animations.
ro.surface_flinger.set_idle_timer_ms: if > 0, min refresh rate will be used when there are no screen updates for the configured timeout.
ro.surface_flinger.set_display_power_timer_ms: if > 0, the default refresh rate will be used when turning on the display (or when going out of AOD) for the configured timeout.
Frame Rate API
The frame rate API lets apps inform the Android platform of their intended frame rate and is available on apps that target Android 11. To learn more about the frame rate API, check out the developer documentation on developer.android.com.
A new developer option has been added to the menu that toggles an overlay on the display with the current refresh rate. The new option is under Settings > System > Developer options > Show refresh rate.