Android 11에서는 여러 새로고침 빈도의 기기 지원을 추가했습니다. 이 기능에는 세 가지 기본 구성요소가 있습니다.
android.hardware.graphics.composer@2.4
에 도입된 새로운 HAL API- 다양한 새로고침 빈도의 기기 설정을 파싱하고 원하는 새로고침 빈도를 설정하는 플랫폼 코드
- 앱이 원하는 프레임 속도를 설정할 수 있는 새로운 SDK 및 NDK API
구현
새로고침 빈도 전환을 위한 전용 지원이 android.hardware.graphics.composer@2.4 HAL
에 추가되었습니다.
이전 버전의 컴포저 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에서 개발자 문서를 참고하세요.
개발자 옵션
현재 새로고침 빈도로 디스플레이의 오버레이를 전환하는 새로운 개발자 옵션이 메뉴에 추가되었습니다. 새로운 옵션은 설정 > 시스템 > 개발자 옵션 > 새로고침 빈도 보기에 있습니다.