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

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

Поверхность

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

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

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

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

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

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

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

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

SurfaceHolder

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

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