Возможности отображения (такие как режимы отображения и поддерживаемые типы HDR) могут динамически изменяться на устройствах с внешним подключением дисплеев (через HDMI или DisplayPort), таких как телевизионные приставки Android TV (STB) и устройства с поддержкой технологии OTT. Это изменение может происходить в результате сигнала горячего подключения HDMI, например, когда пользователь переключается с одного дисплея на другой или загружает устройство без подключенного дисплея. В Android 12 и более поздних версиях внесены изменения в фреймворк для поддержки горячего подключения и динамических возможностей отображения.
На этой странице описывается обработка горячего подключения дисплеев и изменения в возможностях дисплея в реализации Composer HAL. Кроме того, здесь обсуждается управление связанным буфером кадров и предотвращение состояний гонки в таких ситуациях.
Обновление возможностей отображения
В этом разделе описывается, как платформа Android обрабатывает изменения в возможностях отображения, инициированные Composer HAL.
Прежде чем Android сможет корректно обрабатывать изменения в возможностях отображения, OEM-производитель должен реализовать Composer HAL таким образом, чтобы он использовал onHotplug(display, connection=CONNECTED)
для уведомления фреймворка о любых изменениях в возможностях отображения. После этого Android обрабатывает изменения в возможностях отображения следующим образом:
- При обнаружении изменения в возможностях отображения фреймворк получает уведомление
onHotplug(display, connection=CONNECTED)
. - Получив уведомление, фреймворк сбрасывает свое состояние отображения и воссоздает его с новыми возможностями из HAL, используя методы
getActiveConfig
,getDisplayConfigs
,getDisplayAttribute
,getColorModes
,getHdrCapabilities
иgetDisplayCapabilities
. - После того как фреймворк воссоздает новое состояние отображения, он отправляет обратный вызов
onDisplayChanged
приложениям, которые прослушивают такие события.
Фреймворк перераспределяет фреймбуферы при последующих событиях onHotplug(display, connection=CONNECTED)
. Подробнее о том, как правильно управлять памятью фреймбуфера, чтобы избежать сбоев при выделении новых фреймбуферов, см. в разделе Управление фреймбуфером клиента .
Обработка распространенных сценариев подключения
В этом разделе описывается, как правильно обрабатывать различные сценарии подключения в ваших реализациях, когда основной дисплей подключен и отключен.
Разработанный для мобильных устройств, фреймворк Android не имеет встроенной поддержки отключённого основного дисплея. Вместо этого HAL должен заменять основной дисплей на дисплей-заглушку при взаимодействии с фреймворком в случае физического отключения основного дисплея.
В приставках STB и ТВ-адаптерах с внешними дисплеями, которые можно отключить, могут возникнуть следующие сценарии. Для реализации поддержки этих сценариев используйте информацию из таблицы ниже:
Сценарий | Умение обращаться |
---|---|
Нет подключенного дисплея во время загрузки |
|
Основной дисплей физически подключен |
|
Основной дисплей физически отключен |
|
Рекомендации по подключению без HDMI
Android TV поддерживает только следующие разрешения:
- 720x1280
- 1080x1920
- 2160x3840
- 4320x7680
Когда STB или телевизионный адаптер пытается отобразить неподдерживаемое разрешение, например 480i, по соединению CVBS, пользователю отображается сообщение об ошибке.
Если у STB или TV-адаптера есть как HDMI-, так и не-HDMI-подключения, HDMI-подключение является основным дисплеем, а не-HDMI-подключение неактивно. В результате, если HDMI-подключение отключается, а не-HDMI-подключение всё ещё подключено, событие отправляется в SurfaceFlinger, и возможности не-HDMI-дисплея должны быть отражены через getDisplayAttribute
и другие API iComposerClient
(например, getHdrCapabilities
).
Используйте последовательные идентификаторы конфигураций для предотвращения состояний гонки
Состояние гонки может возникнуть, если Composer HAL обновляет поддерживаемые конфигурации отображения одновременно с вызовом фреймворком setActiveConfig
или setActiveConfigWithConstraints
. Решение заключается в реализации Composer HAL для использования последовательных идентификаторов и предотвращения этой проблемы.
В этом разделе описывается, как могут возникнуть условия гонки, а затем приводятся сведения о том, как реализовать Composer HAL таким образом, чтобы он использовал последовательные идентификаторы для предотвращения таких условий.
Рассмотрим следующую последовательность событий, когда новые последовательные идентификаторы НЕ назначаются новым конфигурациям отображения, что приводит к состоянию гонки:
Поддерживаемые идентификаторы конфигураций дисплея:
- id=1 , 1080x1920 60 Гц
- id=2 , 1080x1920 50 Гц
Фреймворк вызывает
setActiveConfig(display, config=1)
.Одновременно с этим Composer HAL обрабатывает изменение конфигураций дисплея и обновляет свое внутреннее состояние новым набором конфигураций дисплея, как показано ниже:
- id=1 , 2160x3840 60 Гц
- id=2 , 2160x3840 50 Гц
- id=3 , 1080x1920 60 Гц
- id=4 , 1080x1920 50 Гц
Composer HAL отправляет событие
onHotplug
фреймворку, чтобы уведомить об изменении набора поддерживаемых режимов.Composer HAL получает
setActiveConfig(display, config=1)
(из шага 2).HAL интерпретирует это так, что фреймворк запросил изменение конфигурации на 2160x3840 60 Гц , хотя на самом деле требовалось 1080x1920 60 Гц .
Процесс с использованием непоследовательного назначения идентификаторов заканчивается здесь неверной интерпретацией желаемого изменения конфигурации.
Настройте Composer HAL для использования последовательных идентификаторов
Чтобы избежать подобных условий гонки, OEM-производитель должен реализовать Composer HAL следующим образом:
- Когда Composer HAL обновляет поддерживаемые конфигурации отображения, он назначает новые последовательные идентификаторы новым конфигурациям отображения.
- Когда фреймворк вызывает
setActiveConfig
илиsetActiveConfigWithConstraints
с недопустимым идентификатором конфигурации, Composer HAL игнорирует вызов.
Эти шаги позволяют предотвратить возникновение состояний гонки, как показано в следующем обсуждении.
Рассмотрим следующую последовательность событий, когда новым конфигурациям отображения присваиваются новые последовательные идентификаторы:
Поддерживаемые идентификаторы конфигураций дисплея:
- id=1 , 1080x1920 60 Гц
- id=2 , 1080x1920 50 Гц
Фреймворк вызывает
setActiveConfig(display, config=1)
.При обработке изменения конфигураций отображения следующий набор идентификаторов конфигураций назначается, начиная со следующего неиспользованного целого числа, как показано ниже:
id=3 , 2160x3840 60 Гц
id=4 , 2160x3840 50 Гц
id=5 , 1080x1920 60 Гц
id=6 , 1080x1920 50 Гц
Composer HAL отправляет фреймворку событие
onHotplug
, чтобы уведомить об изменении набора поддерживаемых режимов.Composer HAL получает
setActiveConfig(display, config=1)
(из шага 2).Composer HAL игнорирует вызов, поскольку идентификатор больше не действителен.
Фреймворк получает и обрабатывает событие
onHotplug
из шага 4. Он обращается к HAL-компоненту Composer, используя функцииgetDisplayConfigs
иgetDisplayAttribute
. С помощью этих функций фреймворк идентифицирует новый идентификатор (5) для требуемого разрешения и частоты обновления 1080x1920 и 60 Гц.Фреймворк отправляет еще одно событие
setActiveConfig
с обновленным идентификатором 5.Composer HAL получает
setActiveConfig(display, config=5)
из шага 5.HAL правильно интерпретирует, что фреймворк запросил изменение конфигурации на 1080x1920 60 Гц.
Как показано в примере выше, процесс, использующий последовательное назначение идентификаторов, гарантирует предотвращение состояния гонки и обновление правильного изменения конфигурации дисплея.