다중 새로 고침 빈도

Android 11은 새로 고침 빈도가 여러 개인 기기에 대한 지원을 추가합니다. 이 기능에는 세 가지 주요 구성 요소가 있습니다.

  • android.hardware.graphics.composer@2.4 에 새로운 HAL API가 도입되었습니다.
  • 다양한 재생 빈도에 대한 장치 구성을 구문 분석하고 원하는 재생 빈도를 설정하는 플랫폼 코드
  • 앱이 원하는 프레임 속도를 설정할 수 있도록 하는 새로운 SDK 및 NDK API

구현

새로 고침 빈도 전환에 대한 전용 지원이 android.hardware.graphics.composer@2.4 HAL 에 추가되었습니다. Composer HAL의 이전 버전은 새로 고침 빈도 전환에 대한 지원이 제한되어 있으므로 이 버전을 사용하는 것이 좋습니다.

구성 그룹

getDisplayAttribute_2_4 API를 사용하여 쿼리할 수 있는 새 속성 CONFIG_GROUPIComposerClient::Attribute 에 추가되었습니다. 이 속성을 통해 공급업체는 디스플레이 구성을 그룹화할 수 있습니다. 동일한 그룹의 구성을 사용하면 대부분의 경우 구성 간에 원활하게 전환할 수 있습니다. 구성 그룹은 구성에 대한 다른 속성이 아닌 새로 고침 빈도를 전환하기 위해 구성 간에 전환할 수 있는 구성을 구분하기 위해 플랫폼에서 사용됩니다.

네 가지 디스플레이 구성을 지원하는 장치에서 구성 그룹을 사용할 때의 이점을 보여주는 다음 예를 고려하십시오.

  • 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 사이에서는 전환할 수 없다는 것을 알고 있습니다. 이렇게 하면 단순히 새로 고침 빈도를 변경하는 대신 구성이 변경됩니다.

작곡가 API 업데이트

getDisplayVsyncPeriod
새로 고침 빈도를 변경할 때 더 나은 제어 및 예측 가능성을 위해 getDisplayVsyncPeriod 가 추가되었습니다. getDisplayVsyncPeriod 는 디스플레이가 작동하는 현재 재생 빈도(vsync 기간 기준)를 반환합니다. 이것은 재생 빈도와 현재 재생 빈도 사이를 전환하는 동안 플랫폼에서 다음 프레임을 시작할 시점을 결정하는 데 필요한 경우 특히 유용합니다.
setActiveConfigWithConstraints
setActiveConfigWithConstraints 메소드는 기존 setActiveConfig 메소드에 대한 새로운 확장이며 구성 변경에 대한 추가 정보를 제공합니다. 제약 조건은 vsyncPeriodChangeConstraints 매개변수의 일부로 제공되며 다음 매개변수를 포함합니다.
    원하는 시간나노
    vsync 기간이 변경될 수 있는 CLOCK_MONOTONIC 의 시간입니다(즉, 이 시간 이전에 vsync 기간이 변경되어서는 안 됨). 이는 플랫폼이 새로 고침 빈도 변경에 대해 미리 계획하고 싶지만 표시할 대기열에 일부 버퍼가 이미 있는 경우에 유용합니다. 플랫폼은 이러한 버퍼를 고려하고 재생 빈도 전환이 가능한 한 원활하게 되도록 이 시간을 적절하게 설정합니다.
    심리스필수
    true인 경우 눈에 띄는 시각적 아티팩트 없이 vsync 기간 변경이 원활하게 발생해야 합니다. 이 플래그는 콘텐츠 변경의 결과로 새로 고침 빈도 변경이 필요할 때 플랫폼에서 사용됩니다(예: 장치가 유휴 상태이고 애니메이션이 시작됨). 이를 통해 공급업체는 눈에 띄는 시각적 아티팩트가 발생할 수 있는 특정 구성 변경을 허용하지 않을 수 있습니다. 구성을 원활하게 변경할 수 없고 seamlessRequiredtrue 로 설정된 경우 구현은 SEAMLESS_NOT_POSSIBLE 을 반환 코드로 반환하고 동일한 구성 변경을 원활하게 수행할 수 있을 때 새로운 onSeamlessPossible 콜백을 호출해야 합니다.

성공 시 구현은 새로 고침 빈도 변경이 발생할 것으로 예상되는 시기를 플랫폼에 알려주는 VsyncPeriodChangeTimeline 을 반환합니다. newVsyncAppliedTimeNanos 매개변수는 새 디스플레이가 새 vsync 기간에 새로 고쳐지기 시작할 때 CLOCK_MONOTONIC 의 시간으로 설정해야 합니다. 이는 desiredTimeNanos 와 함께 플랫폼이 미리 새로 고침 빈도 전환을 계획하고 새 새로 고침 빈도에 대해 앱을 미리 확인할 수 있도록 합니다. 이를 통해 새로 고침 빈도를 원활하게 전환할 수 있습니다.

일부 구현에서는 새로 고침 빈도를 보내기 전에 새로 고침 프레임을 보내야 합니다. 이를 위해 HAL에는 새로 고침 프레임이 필요함을 나타내는 refreshRequired 매개 변수와 새로 고침 프레임을 전송해야 하는 첫 번째 vsync를 나타내는 refreshTimeNanos 가 있습니다.

onVsyncPeriodTimingChanged [콜백]
타임라인의 일부 매개변수가 변경되었고 플랫폼이 타임라인을 조정해야 함을 플랫폼에 나타내기 위해 HAL에서 호출할 수 있는 새 콜백입니다. 이 콜백은 어떤 이유로 HAL의 긴 처리 시간 또는 늦은 새로 고침 프레임으로 인해 이전 타임라인이 누락된 경우 호출될 것으로 예상됩니다.

플랫폼은 재생 빈도를 어떻게 변경하기로 결정합니까?

새로 고침 빈도 선택은 다음 두 시스템 서비스에서 발생합니다.

디스플레이매니저
DisplayManager 는 새로 고침 빈도에 대한 높은 수준의 정책을 설정합니다. Composer HAL 구성과 동일한 기본 디스플레이 구성을 설정합니다. 또한 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를 설정하고 구성의 새로 고침 빈도와 일치하도록 최소 및 최대 새로 고침 빈도를 설정합니다.
    • Battery Saver : 기기가 저전력 모드일 때 재생 빈도가 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 플랫폼에 의도한 프레임 속도를 알릴 수 있으며 Android 11을 대상으로 하는 앱에서 사용할 수 있습니다. 프레임 속도 API에 대해 자세히 알아보려면 developer.android.com 에서 개발자 문서를 확인하세요.

개발자 옵션

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