Сопоставление тонов яркости HDR с диапазоном, совместимым с SDR

В Android 13 представлена статическая библиотека libtonemap, которую можно настроить. Она определяет операции сопоставления тонов и используется процессом SurfaceFlinger и реализациями Hardware Composer (HWC). Эта функция позволяет OEM-производителям определять и передавать свои алгоритмы сопоставления тонов дисплея между фреймворком и поставщиками, чтобы уменьшить расхождение в сопоставлении тонов.

В Android 12 и более ранних версиях операции сопоставления тонов, относящиеся к дисплею, не были общими для HWC, SurfaceFlinger и приложений. В зависимости от пути отрисовки для HDR-контента это приводило к несоответствиям в качестве изображения, поскольку HDR-контент по-разному сопоставлялся с выходным пространством. Это было заметно в таких сценариях, как поворот экрана, когда стратегия композиции меняется между графическим процессором и процессором дисплея, а также в различиях в поведении рендеринга между TextureView и SurfaceView.

На этой странице описаны интерфейс, возможности настройки и сведения о проверке библиотеки libtonemap.

Интерфейс библиотеки сопоставления тонов

Библиотека libtonemap содержит реализации на базе ЦП и шейдеры SkSL, которые могут быть подключены SurfaceFlinger для композиции на базе графического процессора и HWC для создания таблицы поиска сопоставления тонов (LUT). Точкой входа в libtonemap является android::tonemap::getToneMapper, которая возвращает объект, реализующий интерфейс ToneMapper.

Интерфейс ToneMapper поддерживает следующие возможности:

  • Как создать LUT-файл для тональной компрессии

    Интерфейс ToneMapper::lookupTonemapGain – это реализация шейдера, определенного в libtonemap_LookupTonemapGain, на уровне ЦП. Она используется модульным тестированием в фреймворке и может использоваться партнерами для создания LUT сопоставления тонов в конвейере обработки цвета.

    libtonemap_LookupTonemapGain принимает значения цвета в абсолютном ненормализованном линейном пространстве (как в линейном RGB, так и в XYZ) и возвращает число с плавающей запятой, описывающее, на сколько нужно умножить входные цвета в линейном пространстве.

  • Как сгенерировать шейдер SkSL

    Интерфейс ToneMapper::generateTonemapGainShaderSkSL возвращает строку шейдера SkSL, учитывая исходное и целевое цветовое пространство. Шейдер SkSL подключается к реализации Skia для RenderEngine – компонента SurfaceFlinger, который отвечает за композицию с ускорением графического процессора. Шейдер также подключен к libhwui, чтобы можно было эффективно выполнять сопоставление тонов HDR в SDR для TextureView. Поскольку сгенерированная строка встраивается в другие шейдеры SkSL, используемые Skia, шейдер должен соответствовать следующим правилам:

    • У строки шейдера должна быть точка входа с сигнатурой float libtonemap_LookupTonemapGain(vec3 linearRGB, vec3 xyz), где linearRGB – абсолютное значение нит RGB-пикселей в линейном пространстве, а xyz – значение linearRGB, преобразованное в XYZ.
    • Все вспомогательные методы, используемые строкой шейдера, должны иметь префикс libtonemap_, чтобы не возникало конфликтов с определениями шейдеров фреймворка. Аналогично, входные переменные типа uniform должны иметь префикс in_libtonemap_.
  • Генерировать униформы SkSL

    Интерфейс ToneMapper::generateShaderSkSLUniforms возвращает следующие данные, если метаданные struct описывают метаданные из разных стандартов HDR и условий показа:

    • Список переменных, связанных с шейдером SkSL.

    • Единообразные значения in_libtonemap_displayMaxLuminance и in_libtonemap_inputMaxLuminance. Эти значения используются шейдерами фреймворка при масштабировании входных данных в libtonemap и нормализации выходных данных, если применимо.

      Процесс создания униформы не зависит от входного и выходного пространства данных.

Настройка канала

Эталонная реализация библиотеки libtonemap дает приемлемые результаты. Однако алгоритм тональной компрессии, используемый при композиции графического процессора, может отличаться от алгоритма, используемого при композиции процессора дисплея. Поэтому использование эталонной реализации может вызвать мерцание в некоторых сценариях, например при анимации вращения. Настройка позволяет решить проблемы с качеством изображения, характерные для конкретного поставщика.

Производителям настоятельно рекомендуется переопределить реализацию libtonemap, чтобы определить собственный подкласс ToneMapper, который возвращается getToneMapper. При настройке реализации партнеры должны выполнить одно из следующих действий:

  • Изменить реализацию тега libtonemap.
  • Определить собственную статическую библиотеку, скомпилировать ее как отдельный файл и заменить файл .a библиотеки libtonemap на файл, сгенерированный из пользовательской библиотеки.

Поставщикам не нужно изменять код ядра, но им необходимо обмениваться информацией об алгоритмах тональной компрессии DPU, чтобы обеспечить правильную реализацию.

Проверка

Чтобы проверить реализацию, выполните следующие действия:

  1. Воспроизводите HDR-видео на экране с поддержкой любого стандарта HDR, например HLG, HDR10, HDR10+ или DolbyVision.

  2. Переключите композицию графического процессора, чтобы убедиться, что мерцание не заметно для пользователя.

    Чтобы включить или отключить композицию на GPU, используйте следующую команду adb:

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

Распространенные проблемы

При такой реализации могут возникнуть следующие проблемы:

  • Полосы появляются, когда целевой буфер, используемый для композиции на GPU, имеет более низкую точность, чем обычно требуется для HDR-контента. Например, полосы могут появиться, если реализация HWC поддерживает непрозрачные 10-битные форматы для HDR, такие как RGBA1010102 или P010, но требует, чтобы композиция GPU записывалась в 8-битном формате, например RGBA8888, для поддержки альфа-канала.

  • Незначительное изменение цвета вызвано различиями в квантовании, если DPU работает с другой точностью, чем GPU.

Каждая из этих проблем связана с различиями в относительной точности базового оборудования. Обычно для этого на пути с более низкой точностью добавляется этап дизеринга, чтобы разница в точности была менее заметна.