HDR 휘도를 SDR 호환 범위에 매핑하는 톤 매핑

Android 13에는 톤 매핑 작업을 정의하고 SurfaceFlinger 프로세스 및 HWC(Hardware Composer) 구현과 공유되는 libtonemap 이라는 공급업체 구성 가능한 정적 라이브러리가 도입되었습니다. 이 기능을 통해 OEM은 프레임워크와 공급업체 간에 디스플레이 톤 매핑 알고리즘을 정의하고 공유하여 톤 매핑의 불일치를 줄일 수 있습니다.

Android 13 이전에는 디스플레이별 톤 매핑 작업이 HWC, SurfaceFlinger 및 앱 간에 공유되지 않았습니다. 렌더링 경로에 따라 HDR 콘텐츠의 경우 HDR 콘텐츠가 다른 방식으로 출력 공간에 톤 매핑되는 이미지 품질 불일치가 발생했습니다. 이는 GPU와 DPU 간에 구성 전략이 변경되는 화면 회전과 같은 시나리오와 TextureView와 SurfaceView 간의 렌더링 동작 차이에서 감지할 수 있습니다.

이 페이지에서는 libtonemap 라이브러리의 인터페이스, 사용자 정의 및 유효성 검사 세부 정보를 설명합니다.

톤 매핑 라이브러리에 대한 인터페이스

libtonemap 라이브러리에는 GPU 백엔드 구성을 위해 SurfaceFlinger로, 톤 매핑 LUT(룩업 테이블) 생성을 위해 HWC에서 플러그인할 수 있는 CPU 지원 구현 및 SkSL 셰이더가 포함되어 있습니다. libtonemap 의 진입점은 android::tonemap::getToneMapper() 이며, ToneMapper 인터페이스를 구현하는 객체를 반환합니다.

ToneMapper 인터페이스는 다음 기능을 지원합니다.

  • 톤 매핑 LUT 생성

    ToneMapper::lookupTonemapGain 인터페이스는 libtonemap_LookupTonemapGain() 에 정의된 셰이더의 CPU 구현입니다. 이것은 프레임워크의 단위 테스트에서 사용되며 파트너가 색상 파이프라인 내에서 톤 매핑 LUT를 생성하는 데 도움을 주기 위해 사용할 수 있습니다.

    libtonemap_LookupTonemapGain() 은 선형 RGB와 XYZ 모두에서 정규화되지 않은 절대 선형 공간의 색상 값을 가져오고 선형 공간에서 입력 색상을 곱할 정도를 설명하는 부동 소수점을 반환합니다.

  • SkSL 셰이더 생성

    ToneMapper::generateTonemapGainShaderSkSL() 인터페이스는 소스 및 대상 데이터 공간이 주어지면 SkSL 셰이더 문자열을 반환합니다. SkSL 셰이더는 SurfaceFlinger용 GPU 가속 합성 구성 요소인 RenderEngine 용 Skia 구현에 연결됩니다. 셰이더도 libhwui 에 연결되어 HDR-SDR 톤 매핑이 TextureView 에 대해 효율적으로 수행될 수 있습니다. 생성된 문자열은 Skia에서 사용하는 다른 SkSL 셰이더에 인라인되기 때문에 셰이더는 다음 규칙을 따라야 합니다.

    • 셰이더 문자열에는 float libtonemap_LookupTonemapGain(vec3 linearRGB, vec3 xyz) 서명이 있는 진입점이 있어야 합니다. 여기서 linearRGB 는 선형 공간에서 RGB 픽셀의 절대 니트 값이고 xyz 는 XYZ로 변환된 linearRGB 입니다.
    • 프레임워크 셰이더 정의가 충돌하지 않도록 셰이더 문자열에서 사용하는 모든 도우미 메서드는 libtonemap_ 문자열을 접두사로 사용해야 합니다. 마찬가지로 입력 유니폼 앞에는 in_libtonemap_ 접두사가 있어야 합니다.
  • SkSL 유니폼 생성

    ToneMapper::generateShaderSkSLUniforms() 인터페이스는 다양한 HDR 표준 및 디스플레이 조건의 메타데이터를 설명하는 메타데이터 struct 가 주어지면 다음을 반환합니다.

    • SkSL 셰이더에 의해 바인딩된 유니폼 목록입니다.

    • 균일한 값 in_libtonemap_displayMaxLuminancein_libtonemap_inputMaxLuminance . 이 값은 입력을 libtonemap 으로 확장하고 해당하는 경우 출력을 정규화할 때 프레임워크 셰이더에서 사용됩니다.

    현재 유니폼을 생성하는 프로세스는 입력 및 출력 데이터 공간에 구애받지 않습니다.

커스터마이징

libtonemap 라이브러리의 참조 구현은 허용 가능한 결과를 생성합니다. 그러나 GPU 구성에 사용되는 톤 매핑 알고리즘은 DPU 구성에 사용되는 알고리즘과 다를 수 있으므로 참조 구현을 사용하면 회전 애니메이션과 같은 일부 시나리오에서 깜박임이 발생할 수 있습니다. 사용자 지정은 이러한 공급업체별 이미지 품질 문제를 해결할 수 있습니다.

OEM은 getToneMapper() 에 의해 반환되는 자체 ToneMapper 하위 클래스를 정의하기 위해 libtonemap 구현을 재정의할 것을 강력히 권장합니다. 구현을 사용자 정의할 때 파트너는 다음 중 하나를 수행해야 합니다.

  • libtonemap 의 구현을 직접 수정하십시오.
  • 자체 정적 라이브러리를 정의하고 라이브러리를 독립 실행형으로 컴파일하고 libtonemap 라이브러리의 .a 파일을 사용자 정의 라이브러리에서 생성된 파일로 교체합니다.

공급업체는 커널 코드를 수정할 필요가 없지만 여러 공급업체는 적절한 구현을 위해 DPU 톤 매핑 알고리즘에 대한 세부 정보를 전달해야 합니다.

확인

구현을 확인하려면 다음 단계를 따르세요.

  1. HLG, HDR10, HDR10+ 또는 DolbyVision과 같이 디스플레이 시스템이 지원 하는 HDR 표준의 화면에서 HDR 비디오를 재생합니다.

  2. 사용자가 감지할 수 있는 깜박임이 없도록 GPU 구성을 전환합니다.

    다음 adb 명령을 사용하여 GPU 구성을 전환합니다.

    adb shell service call SurfaceFlinger 1008 i32 <0 to enable HWC composition,
    1 to force GPU composition>
    
    

일반적인 문제

이 구현에서는 다음과 같은 문제가 발생할 수 있습니다.

  • 밴딩은 GPU 구성에서 사용하는 렌더 대상이 HDR 콘텐츠의 일반적인 값보다 정밀도가 낮을 ​​때 발생합니다. 예를 들어, 밴딩은 HWC 구현이 RGBA1010102 또는 P010과 같은 HDR용 불투명 10비트 형식을 지원하지만 GPU 구성이 알파를 지원하기 위해 RGBA8888과 같은 8비트 형식으로 작성해야 할 때 발생할 수 있습니다.

  • DPU가 GPU와 다른 정밀도로 작동하는 경우 미묘한 색상 이동은 양자화 차이로 인해 발생합니다.

이러한 각 문제는 기본 하드웨어의 상대적 정밀도 차이와 관련이 있습니다. 일반적인 해결 방법은 정밀도가 낮은 경로에 디더링 단계가 있는지 확인하여 정밀도 차이를 사람이 감지할 수 없도록 만드는 것입니다.