Графическая архитектура

Что каждый разработчик должен знать о поверхностях, SurfaceHolder, EGLSurface, SurfaceView, GLSurfaceView, SurfaceTexture, TextureView, SurfaceFlinger и Vulkan.

На этой странице описываются основные элементы системной графической архитектуры Android и то, как они используются фреймворком приложения и мультимедийной системой. Основное внимание уделяется перемещению буферов графических данных в системе. Если вы когда-либо задумывались о том, почему SurfaceView и TextureView ведут себя именно так, а не иначе, или как взаимодействуют поверхности и EGLSurface, вы попали по адресу.

Предполагается наличие определённого опыта работы с устройствами Android и разработкой приложений. Вам не требуются подробные знания фреймворка приложения, и в нём упоминается лишь небольшое количество вызовов API, но материал не пересекается с другой общедоступной документацией. Цель — предоставить подробную информацию о важных событиях, связанных с отрисовкой кадра для вывода, чтобы помочь вам принимать обоснованные решения при разработке приложения. Для достижения этой цели данный документ разработан снизу вверх, описывая работу классов пользовательского интерфейса, а не способы их использования.

Этот раздел включает несколько страниц, охватывающих всё: от справочных материалов до подробностей HAL и вариантов использования. Он начинается с объяснения графических буферов Android, описывает механизм композиции и отображения, а затем переходит к более высокоуровневым механизмам, предоставляющим данные компоновщику. Рекомендуем читать страницы в следующем порядке, а не перескакивать к интересующей теме.

Низкоуровневые компоненты

  • BufferQueue и gralloc . BufferQueue соединяет объект, генерирующий буферы графических данных ( производитель ), с объектом, принимающим данные для отображения или дальнейшей обработки ( потребитель ). Выделение буферов осуществляется с помощью распределителя памяти gralloc , реализованного через специфичный для поставщика интерфейс HAL.
  • SurfaceFlinger, Hardware Composer и виртуальные дисплеи . SurfaceFlinger принимает буферы данных из нескольких источников, объединяет их и отправляет на дисплей. Уровень аппаратного компоновщика HAL (HWC) определяет наиболее эффективный способ объединения буферов с доступным оборудованием, а виртуальные дисплеи обеспечивают доступ к комбинированному выводу внутри системы (записывая экран или отправляя его по сети).
  • Surface, Canvas и SurfaceHolder . Поверхность создаёт очередь буферов, которая часто используется SurfaceFlinger. При рендеринге на поверхность результат попадает в буфер, который отправляется потребителю. API Canvas предоставляют программную реализацию (с поддержкой аппаратного ускорения) для рисования непосредственно на поверхности (низкоуровневая альтернатива OpenGL ES). Всё, что связано с представлением, подразумевает использование SurfaceHolder, API которого позволяют получать и задавать параметры поверхности, такие как размер и формат.
  • EGLSurface и OpenGL ES . OpenGL ES (GLES) определяет API для рендеринга графики, разработанный для работы с EGL — библиотекой, которая позволяет создавать окна и получать к ним доступ через операционную систему (для отрисовки текстурированных полигонов используйте вызовы GLES; для вывода изображения на экран — вызовы EGL). На этой странице также рассматривается ANativeWindow — эквивалент класса Java Surface в C/C++, используемый для создания оконной поверхности EGL из машинного кода.
  • Vulkan . Vulkan — это кроссплатформенный API с низкими издержками для высокопроизводительной 3D-графики. Как и OpenGL ES, Vulkan предоставляет инструменты для создания высококачественной графики в реальном времени в приложениях. К преимуществам Vulkan относятся снижение нагрузки на процессор и поддержка языка программирования SPIR-V Binary Intermediate .

Компоненты высокого уровня

  • SurfaceView и GLSurfaceView . SurfaceView объединяет поверхность и представление. Компоненты представления SurfaceView формируются с помощью SurfaceFlinger (а не приложения), что позволяет выполнять рендеринг из отдельного потока/процесса и изолировать его от рендеринга пользовательского интерфейса приложения. GLSurfaceView предоставляет вспомогательные классы для управления контекстами EGL, межпотоковым взаимодействием и взаимодействием с жизненным циклом активности (но это не обязательно для использования GLES).
  • SurfaceTexture . SurfaceTexture объединяет поверхность и текстуру GLES для создания очереди BufferQueue, потребителем которой является ваше приложение. Когда производитель помещает новый буфер в очередь, он уведомляет об этом ваше приложение, которое, в свою очередь, освобождает ранее удерживаемый буфер, получает новый буфер из очереди и выполняет вызовы EGL, чтобы сделать буфер доступным для GLES как внешнюю текстуру. В Android 7.0 добавлена ​​поддержка безопасного воспроизведения видео с текстурами, что позволяет выполнять постобработку защищенного видеоконтента с помощью графического процессора.
  • TextureView . TextureView объединяет представление с SurfaceTexture. TextureView оборачивает SurfaceTexture и отвечает за ответ на обратные вызовы и получение новых буферов. При отрисовке TextureView использует содержимое последнего полученного буфера в качестве источника данных, выполняя рендеринг там и так, как указано в состоянии представления. Композиция представления всегда выполняется с помощью GLES, то есть обновление содержимого может привести к перерисовке других элементов представления.