Android 11에서는 여러 새로고침 빈도의 기기 지원을 추가했습니다. 이 기능에는 세 가지 주요 구성요소가 있습니다.
android.hardware.graphics.composer@2.4
에 도입된 새로운 HAL API- 다양한 새로고침 빈도의 기기 설정을 파싱하고 원하는 새로고침 빈도를 설정하는 플랫폼 코드
- 앱이 원하는 프레임 속도를 설정할 수 있는 새로운 SDK 및 NDK API
구현
새로고침 빈도 전환을 위한 전용 지원이 …에 추가되었습니다. 이전 버전의 컴포저 HAL에서는 새로고침 빈도 전환을 제한적으로 지원하므로, 이 버전을 사용하는 것이 좋습니다.
구성 적용 그룹
getDisplayAttribute_2_4
API를 사용하여 쿼리할 수 있는 IComposerClient::Attribute
에 새 속성 CONFIG_GROUP
이 추가되었습니다. 이 속성을 사용하면 공급업체가 디스플레이 구성을 그룹화할 수 있습니다. 동일한 그룹의 구성을 사용하면 대부분의 경우 원활한 전환이 가능합니다. 플랫폼은 구성 적용 그룹을 사용하여 구성의 다른 속성이 아닌 새로고침 빈도를 전환하기 위해 전환할 수 있는 구성을 구분합니다.
다음 예를 통해 4가지 디스플레이 구성을 지원하는 기기에서 구성 적용 그룹을 사용하는 이점을 살펴보겠습니다.
- 1080p@60Hz
- 1080p@90Hz
- 1080i@72Hz
- 1080i@48Hz
기기가 48Hz, 60Hz, 72Hz, 90Hz 새로고침 빈도를 지원하더라도 디스플레이는 다른 모드로 작동하고 60Hz에서 72Hz로 전환하면 디스플레이 구성이 1080p에서 1080i로 변경되며 이러한 변경은 의도한 동작이 아닐 수도 있습니다. 구성 적용 그룹을 사용하면 이 문제를 해결할 수 있습니다. 60Hz와 90Hz를 하나의 구성 적용 그룹에 그룹화하고 48Hz와 72Hz를 다른 구성 적용 그룹에 그룹화하면 플랫폼은 60Hz와 90Hz 간, 그리고 48Hz와 72Hz 간에 전환할 수 있지만 60Hz와 72Hz 간에 전환할 수 없음을 인지합니다. 60Hz와 72Hz 간 전환의 경우 새로고침 빈도를 변경하는 것이 아니라 구성 변경이 발생하기 때문입니다.


Composer API 업데이트
- getDisplayVsyncPeriod
- 새로고침 빈도를 변경할 때 제어와 예측 가능성을 향상하기 위해
getDisplayVsyncPeriod
를 추가했습니다.getDisplayVsyncPeriod
는 현재 디스플레이가 작동하는 새로고침 빈도(vsync 기간)를 반환합니다. 새로고침 빈도 간에 전환하는 경우 플랫폼에서 다음 프레임을 시작할 시기를 결정하는 데 현재 새로고침 빈도가 필요하므로 특히 유용합니다. - setActiveConfigWithConstraints
setActiveConfigWithConstraints
메서드는 기존setActiveConfig
메서드를 새롭게 확장한 것으로, 구성 변경에 관한 추가 정보를 제공합니다. 제약조건은vsyncPeriodChangeConstraints
매개변수의 일부로 지정되며 다음 매개변수를 포함합니다.- desiredTimeNanos
CLOCK_MONOTONIC
의 시간으로, 이 시간 후에 vsync 기간이 변경될 수 있습니다 (즉, 이 시간 전에는 vsync 기간이 변경되면 안 됨). 플랫폼이 새로고침 빈도 변경을 미리 계획하고자 하지만 큐에 이미 제공할 버퍼가 있는 경우에 유용합니다. 플랫폼은 이러한 버퍼를 감안하고 새로고침 빈도 전환이 최대한 원활하게 이루어지도록 적절하게 이 시간을 설정합니다.- seamlessRequired
- true인 경우 vsync 기간 변경이 눈에 띄는 시각적 아티팩트 없이 원활하게 이루어져야 합니다. 이 플래그는 콘텐츠 변경 (예: 기기가 유휴 상태일 때 애니메이션이 시작됨)으로 인해 새로고침 빈도를 변경해야 할 때 플랫폼에서 사용됩니다. 이러한 플래그 사용을 통해 공급업체는 눈에 띄는 시각적 아티팩트로 이어질 수 있는 특정 구성 변경을 허용하지 않을 수 있습니다. 구성을 원활하게 변경할 수 없는 경우
seamlessRequired
가true
로 설정되어 있으면 구현에서 반환 코드로SEAMLESS_NOT_POSSIBLE
을 반환하고 새로운 구성 변경을 원활하게 처리할 수 있을 때 새onSeamlessPossible
콜백을 호출해야 합니다. 성공하는 경우 새로고침 빈도 변경이 발생할 예상 시점을 플랫폼에 알리는
VsyncPeriodChangeTimeline
이 반환됩니다.newVsyncAppliedTimeNanos
매개변수는 새 디스플레이가 새 vsync 기간에서 새로고침되기 시작하는CLOCK_MONOTONIC
의 시간으로 설정해야 합니다. 이 매개변수를desiredTimeNanos
와 함께 사용하면 플랫폼에서 새로고침 빈도 전환을 미리 계획하고 앱에 새 새로고침 빈도를 적용할 시간을 계산하기 시작할 수 있습니다. 이렇게 하면 새로고침 빈도를 원활하게 전환할 수 있습니다.일부 구현에서는 새로고침 빈도를 전송하기 전에 새로고침 프레임을 전송해야 합니다. 따라서 HAL에는 새로고침 프레임이 필요함을 나타내는
refreshRequired
매개변수와 새로고침 프레임을 전송해야 하는 기준이 되는 첫 번째 vsync를 나타내는refreshTimeNanos
매개변수가 있습니다.- onVsyncPeriodTimingChanged [콜백]
- 타임라인의 일부 매개변수가 변경되었으며 플랫폼에서 타임라인을 조정해야 함을 나타내기 위해 HAL이 호출할 수 있는 새 콜백입니다. 어떤 이유로든 HAL의 오랜 처리 시간 또는 늦은 새로고침 프레임으로 인해 이전 타임라인이 누락된 경우 이 콜백을 호출해야 합니다.
플랫폼에서 새로고침 빈도를 변경하기로 결정하는 방법
새로고침 빈도 선택은 다음 두 가지 시스템 서비스에서 이루어집니다.
- DisplayManager
DisplayManager
는 새로고침 빈도와 관련된 최상위 정책을 설정합니다. 컴포저 HAL 구성과 동일한 기본 디스플레이 구성을 설정합니다. 또한 새로고침 빈도로 선택할SurfaceFlinger
의 최솟값과 최댓값 범위를 설정합니다.- SurfaceFlinger
- 기본 구성과 동일한 구성 적용 그룹에 있는 구성을 설정하고 최소/최대 범위 내의 새로고침 빈도를 사용하여 새로고침 빈도를 결정합니다.
디스플레이 관리자는 다음 단계에 따라 정책을 결정합니다.
SurfaceFlinger
에서 활성 구성을 쿼리하여 기본 구성 ID 찾기- 시스템 조건을 반복하여 최소값과 최대값의 범위 제한
- 기본 새로고침 빈도 설정: 기본 새로고침 빈도 값은
R.integer.config_defaultRefreshRate
구성 오버레이에서 설정됩니다. 이 값은 애니메이션 및 터치 상호작용과 관련하여 표준 기기 새로고침 빈도를 결정하는 데 사용됩니다. - 최대 새로고침 빈도 설정: 최대 새로고침 빈도 값은
Settings.System.PEAK_REFRESH_RATE
에서 읽습니다. 이 값은 현재 기기 설정 (예: 메뉴 옵션의 설정)을 반영하여 런타임에 변경됩니다. 기본값은R.integer.config_defaultPeakRefreshRate
구성 오버레이에서 설정됩니다. - 최소 새로고침 빈도 설정: 최소 새로고침 빈도 값은
Settings.System.MIN_REFRESH_RATE
에서 읽습니다. 이 값은 현재 기기 설정 (예: 메뉴 옵션의 설정)을 반영하여 런타임에 변경될 수 있습니다. 기본값은 0이므로, 기본 최소값이 없습니다. - 애플리케이션에서 요청된 ModeId: 앱이 디스플레이가 작동하는 기본 구성을 반영하도록
WindowManager.LayoutParams.preferredDisplayModeId
를 설정할 수 있습니다. 대부분의 조건에서DisplayManager
는 적절하게 기본 구성 ID를 설정하고 구성의 새로고침 빈도와 일치하도록 새로고침 빈도 최소값과 최대값을 설정합니다. - 절전 모드: 기기가 저전력 모드일 때 화면 재생 빈도는 60Hz 이하로 제한되고
Settings.Global.LOW_POWER_MODE.
를 통해 표시됩니다.
- 기본 새로고침 빈도 설정: 기본 새로고침 빈도 값은
DisplayManager
가 정책을 설정하면 SurfaceFlinger
는 활성 레이어(프레임 업데이트 대기열을 만드는 레이어)를 기반으로 새로고침 빈도를 설정합니다. 레이어 소유자가 프레임 속도를 설정하면 SurfaceFlinger는 프레임 속도의 배수인 새로고침 빈도를 설정하려고 시도합니다.
예를 들어 두 활성 레이어에서 프레임 속도를 24 및 60으로 설정했다면 SurfaceFlinger는 사용 가능한 경우 120Hz를 선택합니다. 이러한 새로고침 빈도를 사용할 수 없는 경우에는 SurfaceFlinger가 프레임 속도에 최소한의 오류가 있는 새로고침 빈도를 선택합니다. 자세한 내용은 developer.android.com의 개발자 문서를 참고하세요.
SurfaceFlinger
는 다음 플래그를 유지관리하여 새로고침 빈도가 결정되는 방식을 제어합니다.
ro.surface_flinger.use_content_detection_for_refresh_rate:
설정하는 경우 프레임 속도가 설정되지 않은 경우에도 새로고침 빈도는 활성 레이어에 따라 결정됩니다. SurfaceFlinger는 버퍼에 연결된 프레젠테이션 타임스탬프를 확인하여 레이어가 버퍼를 게시하는 평균 fps를 찾는 휴리스틱을 유지관리합니다.ro.surface_flinger.set_touch_timer_ms
: 0보다 큰 경우, 구성된 제한 시간 내에 사용자가 화면을 터치하면 기본 새로고침 빈도가 사용됩니다. 이 휴리스틱은 처리되어 애니메이션의 기본 새로고침 빈도를 준비합니다.ro.surface_flinger.set_idle_timer_ms
: 0보다 큰 경우, 구성 제한 시간 동안 화면 업데이트가 없으면 최소 새로고침 빈도가 사용됩니다.ro.surface_flinger.set_display_power_timer_ms
: 0보다 큰 경우, 구성된 제한 시간 내에 디스플레이를 켜거나 AOD에서 벗어나면 기본 새로고침 빈도가 사용됩니다.
프레임 속도 API
프레임 속도 API는 Android 11을 타겟팅하는 앱에 사용할 수 있으며 앱은 이 API를 사용하여 의도한 프레임 속도를 Android 플랫폼에 알릴 수 있습니다. 프레임 속도 API에 관해 자세히 알아보려면 developer.android.com에서 개발자 문서를 참고하세요.
개발자 옵션

현재 새로고침 빈도로 디스플레이의 오버레이를 전환하는 새로운 개발자 옵션이 메뉴에 추가되었습니다. 새로운 옵션은 설정 > 시스템 > 개발자 옵션 > 새로고침 빈도 보기에 있습니다.