Архитектура графики

Что нужно знать разработчику о платформах, 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, межпотоковой связью и взаимодействием с жизненным циклом объекта activity (но не является обязательным для использования GLES).
  • SurfaceTexture. SurfaceTexture объединяет поверхность и текстуру GLES, чтобы создать BufferQueue, потребителем которого является ваше приложение. Когда производитель ставит в очередь новый буфер, он уведомляет ваше приложение, которое, в свою очередь, освобождает ранее удерживаемый буфер, получает новый буфер из очереди и выполняет вызовы EGL, чтобы сделать буфер доступным для GLES в качестве внешней текстуры. В Android 7.0 добавлена поддержка воспроизведения защищенного видеоконтента с помощью безопасных текстур, что позволяет графическому процессору выполнять постобработку защищенного видеоконтента.
  • TextureView. TextureView объединяет представление с SurfaceTexture. TextureView упаковывает SurfaceTexture и отвечает за реагирование на обратные вызовы и получение новых буферов. При отрисовке TextureView использует в качестве источника данных содержимое последнего полученного буфера, отрисовывая его в соответствии с состоянием представления. Компоновка изображений всегда выполняется с помощью GLES, поэтому при изменении контента могут перерисовываться и другие элементы.