Поверхностные объекты позволяют приложениям отображать изображения на экранах. Интерфейсы 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, работают на самой поверхности.