Внедрить аппаратный композитор HAL

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

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

Реализации 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 упоминаются по именам в стиле lowerCamelCase, которые не существуют в интерфейсе как именованные поля. Почти каждая функция загружается путем запроса указателя функции с помощью 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 составляет слои через резервный режим GPU.

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

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

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

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

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

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

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

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

// In Android 9 and lower:

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

// In Android 10 and higher:

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

Виртуальная композиция дисплея

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

Режимы

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

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

Формат вывода

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

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

Синхронизирующие ограждения

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

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

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

Дополнительную информацию о границах синхронизации см. в разделе Интеграция Hardware Composer .