Объекты 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, работают на самой поверхности.