Обработка горячего подключения в Composer HAL

Возможности отображения (такие как режимы отображения и поддерживаемые типы HDR) могут динамически изменяться на устройствах с внешними дисплеями (через HDMI или DisplayPort), таких как телеприставки Android TV (STB) и устройства Over-the-top (OTT). устройства. Это изменение может произойти в результате сигнала горячего подключения HDMI, например, когда пользователь переключается с одного дисплея на другой или загружает устройство без подключенного дисплея. Начиная с Android 12, в структуру были внесены изменения для поддержки возможностей горячего подключения и динамического отображения.

На этой странице рассказывается, как обрабатывать «горячие» подключения дисплея и изменения возможностей дисплея в реализации Composer HAL. Кроме того, в нем обсуждается, как управлять соответствующим буфером кадра и предотвращать условия гонки в таких ситуациях.

Обновление возможностей отображения

В этом разделе описывается, как платформа Android обрабатывает изменения в возможностях отображения, инициированные Composer HAL.

Прежде чем Android сможет правильно обрабатывать изменения в возможностях отображения, OEM-производитель должен внедрить Composer HAL таким образом, чтобы он использовал onHotplug(display, connection=CONNECTED) для уведомления платформы о любых изменениях возможностей отображения. Как только это реализовано, Android обрабатывает изменения возможностей отображения следующим образом:

  1. При обнаружении изменения возможностей отображения платформа получает onHotplug(display, connection=CONNECTED) .
  2. При получении уведомления инфраструктура отбрасывает свое состояние отображения и воссоздает его с новыми возможностями из HAL с помощью getActiveConfig , getDisplayConfigs , getDisplayAttribute , getColorModes , getHdrCapabilities и getDisplayCapabilities .
  3. Как только платформа воссоздает новое состояние отображения, она отправляет обратный вызов onDisplayChanged приложениям, которые прослушивают такие события.

Платформа перераспределяет буферы кадра при последующих onHotplug(display, connection=CONNECTED) . См. Управление памятью кадрового буфера для получения дополнительной информации о том, как справиться с этим.

Обработка распространенных сценариев подключения

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

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

Следующие сценарии могут возникать в телевизионных приставках и телевизионных адаптерах, которые имеют внешне подключенные дисплеи, которые можно отключить. Чтобы реализовать поддержку этих сценариев, используйте информацию в таблице ниже:

Сценарий Умение обращаться
Нет подключенного дисплея во время загрузки
  • Отправьте onHotplug(display, connection=CONNECTED) из Composer HAL в фреймворк.
  • Замените физическое состояние отображения внутри Composer HAL состоянием отображения заполнителя.

    Примечание. Мы рекомендуем, чтобы дисплей-заполнитель имел один поддерживаемый режим с разрешением 1080 x 1920 и частотой обновления 60 Гц, так как этот режим отображения поддерживается большинством приложений.

Основной дисплей физически подключен
  • Отправьте еще одно onHotplug(display, connection=CONNECTED) из Composer HAL в фреймворк.

    Это приводит к тому, что платформа перезагружает все возможности отображения.

Основной дисплей физически отключен
  • Отправьте еще одно onHotplug(display, connection=CONNECTED) из Composer HAL в фреймворк.
  • Замените физическое состояние отображения внутри Composer HAL состоянием отображения заполнителя. Отображение заполнителя должно иметь один режим отображения, чтобы платформа отправляла обратный вызов onDisplayChanged приложениям (поскольку набор поддерживаемых режимов изменился). Этот режим одного дисплея должен соответствовать последнему активному режиму физического дисплея перед отключением, чтобы приложения не получали события изменения конфигурации .

Управление памятью фреймбуфера

Когда уже подключенный дисплей получает последующее событие уведомления onHotplug(display, connection=CONNECTED) , платформа перераспределяет буферы кадра, связанные с этим дисплеем. Реализации устройств должны предвидеть такое поведение и должным образом управлять памятью кадрового буфера. При реализации используйте следующие рекомендации:

  • Перед отправкой последующих событий уведомления onHotplug(display, connection=CONNECTED) обязательно освободите дескрипторы кадровых буферов, чтобы система могла правильно их освободить, прежде чем перераспределять их. Если освобождение не удалось, перераспределение может завершиться ошибкой из-за нехватки памяти.

  • Мы рекомендуем выделять выделенный пул памяти для кадровых буферов, отделенный от остальной части буфера графической памяти.

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

Использование последовательных идентификаторов конфигурации для предотвращения условий гонки

Условия гонки могут возникнуть, если Composer HAL обновляет поддерживаемые конфигурации дисплея одновременно с фреймворком, вызывающим setActiveConfig или setActiveConfigWithConstraints . Решение состоит в том, чтобы реализовать Composer HAL для использования последовательных идентификаторов и предотвращения этой проблемы.

В этом разделе описывается, как могут возникнуть условия гонки, а затем подробно о том, как реализовать Composer HAL, чтобы он использовал последовательные идентификаторы для предотвращения таких условий.

Рассмотрим следующую последовательность событий, когда новые последовательные идентификаторы НЕ назначаются новым конфигурациям дисплея, вызывая состояние гонки:

  1. Поддерживаемые идентификаторы конфигурации дисплея:

    • id=1 , 1080x1920 60 Гц
    • ID=2 , 1080x1920 50 Гц
  2. Фреймворк вызывает setActiveConfig(display, config=1) .

  3. Одновременно Composer HAL обрабатывает изменение конфигураций дисплея и обновляет свое внутреннее состояние до нового набора конфигураций дисплея, как показано ниже:

    • id=1 , 2160x3840 60 Гц
    • id=2 , 2160x3840 50 Гц
    • ID=3 , 1080x1920 60 Гц
    • ID=4 , 1080x1920 50 Гц
  4. Composer HAL отправляет событие onHotplug в фреймворк, чтобы уведомить об изменении набора поддерживаемых режимов.

  5. Composer HAL получает setActiveConfig(display, config=1) (из шага 2).

  6. HAL интерпретирует, что фреймворк запросил изменение конфигурации на 2160x3840 60hz , хотя на самом деле было желательно 1080x1920 60hz .

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

Настройка Composer HAL для использования последовательных идентификаторов

Чтобы избежать таких условий гонки, OEM-производитель должен реализовать Composer HAL следующим образом:

  • Когда Composer HAL обновляет поддерживаемые конфигурации дисплея, он назначает новые последовательные идентификаторы новым конфигурациям дисплея.
  • Когда платформа вызывает setActiveConfig или setActiveConfigWithConstraints с недопустимым идентификатором конфигурации, Composer HAL игнорирует вызов.

Эти шаги служат для предотвращения условий гонки, как показано в следующем обсуждении.

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

  1. Поддерживаемые идентификаторы конфигурации дисплея:

    • id=1 , 1080x1920 60 Гц
    • ID=2 , 1080x1920 50 Гц
  2. Фреймворк вызывает setActiveConfig(display, config=1) .

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

    • id=3 , 2160x3840 60 Гц

    • id=4 , 2160x3840 50 Гц

    • ID=5 , 1080x1920 60 Гц

    • ID=6 , 1080x1920 50 Гц

  4. Composer HAL отправляет событие onHotplug в инфраструктуру, чтобы уведомить об изменении набора поддерживаемых режимов.

  5. Composer HAL получает setActiveConfig(display, config=1) (из шага 2).

  6. Composer HAL игнорирует вызов, поскольку идентификатор больше недействителен.

  7. Фреймворк получает и обрабатывает событие onHotplug с шага 4. Он вызывает Composer HAL с помощью функций getDisplayConfigs и getDisplayAttribute . С помощью этих функций фреймворк идентифицирует новый идентификатор (5) для нужного разрешения и частоты обновления 1080x1920 и 60 Гц.

  8. Платформа отправляет еще одно событие setActiveConfig с обновленным идентификатором 5.

  9. Composer HAL получает setActiveConfig(display, config=5) с шага 5.

  10. HAL правильно интерпретирует, что фреймворк запросил изменение конфигурации на 1080x1920 60 Гц.

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