В 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, чтобы обеспечить правильную реализацию.
Проверка
Чтобы проверить реализацию, выполните следующие действия:
Воспроизводите HDR-видео на экране с поддержкой любого стандарта HDR, например HLG, HDR10, HDR10+ или DolbyVision.
Переключите композицию графического процессора, чтобы убедиться, что мерцание не заметно для пользователя.
Чтобы включить или отключить композицию на 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.
Каждая из этих проблем связана с различиями в относительной точности базового оборудования. Обычно для этого на пути с более низкой точностью добавляется этап дизеринга, чтобы разница в точности была менее заметна.