Внедрение аппаратного компоновщика HAL

Составные слои HAL аппаратного компоновщика (HWC), полученные от SurfaceFlinger, уменьшают количество композиций, выполняемых OpenGL ES (GLES) и графическим процессором.

HWC абстрагирует объекты, такие как наложения и 2D-блитеры, на составные поверхности и взаимодействует со специализированным оборудованием для композиции окон с составными окнами. Используйте HWC для объединения окон вместо соединения SurfaceFlinger с графическим процессором. Большинство графических процессоров не оптимизированы для композиции, и когда графический процессор компонует слои из SurfaceFlinger, приложения не могут использовать графический процессор для собственного рендеринга.

Реализации HWC должны поддерживать:

  • Не менее четырех наложений:
    • Статус бар
    • Системная панель
    • Приложение
    • Обои/фон
  • Слои, которые больше, чем дисплей (например, обои)
  • Одновременное предварительно умноженное альфа-смешивание для каждого пикселя и альфа-смешивание для каждой плоскости
  • Аппаратный путь для защищенного воспроизведения видео
  • Порядок упаковки RGBA, форматы YUV, а также свойства мозаики, свизла и шага

Для реализации HWC:

  1. Внедрите недействующий HWC и отправьте всю работу по композиции в GLES.
  2. Реализуйте алгоритм для постепенного делегирования композиции HWC. Например, делегируйте аппаратному наложению HWC только первые три или четыре поверхности.
  3. Оптимизировать HWC. Это может включать:
    • Выбор поверхностей, максимально снимающих нагрузку с графического процессора, и отправка их на HWC.
    • Определение того, обновляется ли экран. Если это не так, делегируйте композицию GLES вместо HWC для экономии энергии. Когда экран снова обновится, продолжайте выгружать композицию в HWC.
    • Подготовка к распространенным случаям использования, таким как:
      • Главный экран, который включает в себя строку состояния, системную панель, окно приложения и живые обои.
      • Полноэкранные игры в портретном и ландшафтном режимах
      • Полноэкранное видео с субтитрами и контролем воспроизведения
      • Защищенное воспроизведение видео
      • Многооконный режим с разделенным экраном

HWC-примитивы

HWC предоставляет два примитива, слои и дисплеи , для представления работы композиции и ее взаимодействия с аппаратным обеспечением дисплея. HWC также обеспечивает контроль над VSYNC и обратный вызов SurfaceFlinger, чтобы уведомить его о возникновении события VSYNC.

HIDL-интерфейс

Android 8.0 и более поздние версии используют интерфейс HIDL под названием Composer HAL для связывания IPC между HWC и SurfaceFlinger. Composer HAL заменяет устаревший интерфейс hwcomposer2.h . Если поставщики предоставляют реализацию Composer HAL для HWC, Composer HAL напрямую принимает вызовы HIDL от SurfaceFlinger. Если поставщики предоставляют устаревшую реализацию HWC, Composer HAL загружает указатели функций из hwcomposer2.h , перенаправляя вызовы HIDL в вызовы указателей функций.

HWC предоставляет функции для определения свойств данного дисплея; для переключения между различными конфигурациями дисплея (например, разрешением 4k или 1080p) и цветовыми режимами (например, собственным цветом или настоящим sRGB); и включать, выключать или переводить дисплей в режим пониженного энергопотребления, если он поддерживается.

Указатели функций

Если поставщики реализуют Composer HAL напрямую, SurfaceFlinger вызывает свои функции через HIDL IPC. Например, чтобы создать слой, SurfaceFlinger вызывает createLayer() в Composer HAL.

Если поставщики реализуют интерфейс hwcomposer2.h , Composer HAL вызывает указатели функций hwcomposer2.h . В комментариях hwcomposer2.h на функции интерфейса HWC ссылаются именами в нижнем верблюжьем регистре, которые не существуют в интерфейсе как именованные поля. Почти каждая функция загружается путем запроса указателя функции с помощью getFunction , предоставляемого hwc2_device_t . Например, функция createLayer — это указатель на функцию типа HWC2_PFN_CREATE_LAYER , который возвращается, когда перечислимое значение HWC2_FUNCTION_CREATE_LAYER передается в getFunction .

Подробную документацию по функциям Composer HAL и функциям транзита функций HWC см. в разделе composer . Подробную документацию по указателям функций HWC см. в hwcomposer2.h .

Маркеры слоя и отображения

Слои и дисплеи управляются дескрипторами, созданными HWC. Ручки непрозрачны для SurfaceFlinger.

Когда SurfaceFlinger создает новый слой, он вызывает createLayer , который возвращает тип Layer для прямых реализаций или hwc2_layer_t для сквозных реализаций. Когда SurfaceFlinger изменяет свойство этого слоя, SurfaceFlinger передает значение hwc2_layer_t в соответствующую функцию модификации вместе с любой другой информацией, необходимой для внесения модификации. Тип hwc2_layer_t достаточно велик, чтобы содержать либо указатель, либо индекс.

Физические дисплеи создаются путем горячего подключения. Когда физический дисплей подключается в горячем режиме, HWC создает дескриптор и передает дескриптор SurfaceFlinger через обратный вызов горячего подключения. Виртуальные дисплеи создаются SurfaceFlinger, вызывающим createVirtualDisplay() для запроса отображения. Если HWC поддерживает композицию виртуального дисплея, он возвращает дескриптор. Затем SurfaceFlinger делегирует композицию дисплеев HWC. Если HWC не поддерживает композицию виртуального дисплея, SurfaceFlinger создает дескриптор и компонует дисплей.

Показать операции композиции

Один раз для VSYNC SurfaceFlinger просыпается, если у него есть новый контент для компоновки. Этим новым содержимым могут быть новые буферы изображений из приложений или изменение свойств одного или нескольких слоев. Когда SurfaceFlinger пробуждает его:

  1. Обрабатывает транзакции, если они есть.
  2. Фиксирует новые графические буферы, если они есть.
  3. Выполняет новую композицию, если шаг 1 или 2 привел к изменению содержимого дисплея.

Чтобы выполнить новую композицию, SurfaceFlinger создает и уничтожает слои или изменяет состояния слоев, если это применимо. Он также обновляет слои с их текущим содержимым, используя такие вызовы, как setLayerBuffer или setLayerColor . После того, как все слои будут обновлены, SurfaceFlinger вызывает validateDisplay , который сообщает HWC проверить состояние слоев и определить, как будет продолжаться композиция. По умолчанию SurfaceFlinger пытается настроить каждый слой так, чтобы слой был составлен HWC; хотя в некоторых случаях SurfaceFlinger объединяет слои с помощью отката графического процессора.

После вызова validateDisplay SurfaceFlinger вызывает getChangedCompositionTypes , чтобы узнать, хочет ли HWC изменить какой-либо тип композиции слоя перед выполнением композиции. Чтобы принять изменения, SurfaceFlinger вызывает acceptDisplayChanges .

Если какие-либо слои помечены для композиции SurfaceFlinger, SurfaceFlinger объединяет их в целевой буфер. Затем SurfaceFlinger вызывает setClientTarget , чтобы передать буфер отображению, чтобы буфер можно было отобразить на экране или дополнительно скомпоновать со слоями, которые не были отмечены для композиции SurfaceFlinger. Если для композиции SurfaceFlinger не помечены слои, SurfaceFlinger пропускает этап композиции.

Наконец, SurfaceFlinger вызывает presentDisplay , чтобы указать HWC завершить процесс композиции и отобразить окончательный результат.

Несколько дисплеев

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

  • Предполагается, что имеется ровно один внутренний дисплей. Внутренний дисплей — это дисплей, о котором сообщает начальное горячее подключение во время загрузки. После горячего подключения внутреннего дисплея его нельзя отключить.
  • В дополнение к внутреннему дисплею любое количество внешних дисплеев может быть подключено во время нормальной работы устройства. Платформа предполагает, что все горячие подключения после первого внутреннего дисплея являются внешними дисплеями, поэтому, если добавляются дополнительные внутренние дисплеи, они неправильно классифицируются как Display.TYPE_HDMI вместо Display.TYPE_BUILT_IN .

Хотя описанные выше операции SurfaceFlinger выполняются для каждого дисплея, они выполняются последовательно для всех активных дисплеев, даже если обновляется содержимое только одного дисплея.

Например, если внешний дисплей обновляется, последовательность следующая:

// In Android 9 and lower:

// Update state for internal display
// Update state for external display
validateDisplay(<internal display>)
validateDisplay(<external display>)
presentDisplay(<internal display>)
presentDisplay(<external display>)

// In Android 10 and higher:

// Update state for internal display
// Update state for external display
validateInternal(<internal display>)
presentInternal(<internal display>)
validateExternal(<external display>)
presentExternal(<external display>)

Состав виртуального дисплея

Композиция виртуального дисплея аналогична композиции внешнего дисплея. Разница между композицией виртуального дисплея и композицией физического дисплея заключается в том, что виртуальные дисплеи отправляют вывод в буфер Gralloc, а не на экран. Аппаратный компоновщик (HWC) записывает выходные данные в буфер, обеспечивает ограничение завершения и отправляет буфер потребителю (например, видеокодеру, графическому процессору, центральному процессору и т. д.). Виртуальные дисплеи могут использовать 2D/блиттер или наложения, если конвейер дисплея записывает в память.

Режимы

Каждый кадр находится в одном из трех режимов после того, как SurfaceFlinger вызывает метод HWC validateDisplay() :

  • GLES — графический процессор объединяет все слои, записывая их непосредственно в выходной буфер. HWC не участвует в композиции.
  • СМЕШАННЫЙ — GPU объединяет некоторые слои в буфер кадра, а HWC объединяет буфер кадра и остальные слои, записывая непосредственно в выходной буфер.
  • HWC — HWC объединяет все слои и записывает непосредственно в выходной буфер.

Выходной формат

Форматы вывода буфера виртуального дисплея зависят от их режима:

  • Режим GLES — драйвер EGL устанавливает формат выходного буфера в dequeueBuffer() , обычно RGBA_8888 . Потребитель должен быть в состоянии принять выходной формат, установленный драйвером, иначе буфер не может быть прочитан.
  • Режимы MIXED и HWC — если потребителю требуется доступ к ЦП, потребитель устанавливает формат. В противном случае используется формат IMPLEMENTATION_DEFINED , и Gralloc устанавливает наилучший формат на основе флагов использования. Например, Gralloc устанавливает формат YCbCr, если потребителем является видеокодер и HWC может эффективно записывать этот формат.

Заборы синхронизации

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

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

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

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