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

Возможности дисплея (такие как режимы отображения и поддерживаемые типы HDR) могут динамически изменяться на устройствах, которые имеют внешние подключенные дисплеи (через HDMI или DisplayPort), например, телевизионные приставки Android (STB) и поверх (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) сигнал от композитора HAL к каркасу.
  • Замените физическое состояние отображения внутри Composer HAL на состояние отображения-заполнителя.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    • ID = 1, 1080x1920 60Hz
    • ID = 2, 1080x1920 50Гц
  2. Рамка вызывает setActiveConfig(display, config=1) .

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

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

  5. Композитор HAL получает setActiveConfig(display, config=1) (со стадии 2).

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

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

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

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

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

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

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

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

    • ID = 1, 1080x1920 60Hz
    • ID = 2, 1080x1920 50Гц
  2. Рамка вызывает setActiveConfig(display, config=1) .

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

    • ID = 3, 2160x3840 60Hz

    • ID = 4, 2160x3840 50Гц

    • ID = 5, 1080x1920 60Hz

    • ID = 6, 1080x1920 50Гц

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

  5. Композитор HAL получает setActiveConfig(display, config=1) (со стадии 2).

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

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

  8. Рамки посылает другое setActiveConfig событие с обновленным идентификатором 5.

  9. Композитор HAL получает setActiveConfig(display, config=5) с шагом 5.

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

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