Поверхность и держатель поверхности

Объекты Surface позволяют приложениям отображать изображения на экранах. Интерфейсы SurfaceHolder позволяют приложениям редактировать поверхности и управлять ими.

Поверхность

Поверхность — это интерфейс для производителя для обмена буферами с потребителем.

BufferQueue для поверхности отображения обычно настраивается для тройной буферизации. Буферы выделяются по требованию, поэтому, если производитель генерирует буферы достаточно медленно, например, со скоростью 30 кадров в секунду на дисплее с частотой 60 кадров в секунду, в очереди может быть только два выделенных буфера. Выделение буферов по требованию помогает минимизировать потребление памяти. Вы можете увидеть сводную информацию о буферах, связанных с каждым слоем, в выходных данных dumpsys SurfaceFlinger .

Большинство клиентов выполняют рендеринг на поверхности с помощью OpenGL ES или Vulkan . Однако некоторые клиенты выполняют рендеринг на поверхности с помощью холста.

Рендеринг холста

Реализация холста предоставлена ​​Skia Graphics Library . Если вы хотите нарисовать прямоугольник, вы вызываете Canvas API, который соответствующим образом устанавливает байты в буфере. Чтобы гарантировать, что буфер не будет обновляться двумя клиентами одновременно или записываться в него во время отображения, заблокируйте буфер для доступа к нему. Используйте следующие команды для работы с блокировками холста:

  • lockCanvas() блокирует буфер для рендеринга в ЦП и возвращает Canvas для использования для рисования.
  • unlockCanvasAndPost() разблокирует буфер и отправляет его в наборщик.
  • lockHardwareCanvas() блокирует буфер для рендеринга на графическом процессоре и возвращает холст для рисования.

Когда производитель впервые запрашивает буфер из BufferQueue, буфер выделяется и инициализируется нулем. Инициализация необходима, чтобы избежать непреднамеренного обмена данными между процессами. Однако если вы повторно используете буфер, предыдущее содержимое все равно будет присутствовать. Если вы повторно вызываете lockCanvas() и unlockCanvasAndPost() ничего не рисуя, производитель переключается между ранее визуализированными кадрами.

Код блокировки/разблокировки поверхности сохраняет ссылку на ранее визуализированный буфер. Если вы укажете «грязную» область при блокировке поверхности, она скопирует не «грязные» пиксели из предыдущего буфера. SurfaceFlinger или HWC обычно обрабатывают буфер; но поскольку нам нужно только читать из буфера, нет необходимости ждать монопольного доступа.

ПоверхностьДержатель

SurfaceHolder — это интерфейс, который система использует для совместного использования поверхностей с приложениями. Некоторым клиентам, работающим с поверхностями, нужен SurfaceHolder, поскольку API для получения и установки параметров поверхности реализуются через SurfaceHolder. SurfaceView содержит SurfaceHolder.

Большинство компонентов, взаимодействующих с представлением, включают SurfaceHolder. Некоторые другие API, такие как MediaCodec, работают на самой поверхности.