Что каждый разработчик должен знать о поверхностях: 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 принимает буферы данных из нескольких источников, объединяет их и отправляет на дисплей. Hardware Composer HAL (HWC) определяет наиболее эффективный способ объединения буферов с доступным оборудованием, а виртуальные дисплеи делают составной вывод доступным внутри системы (запись экрана или отправка экрана по сети).
- Поверхность, холст и SurfaceHolder . Поверхность создает буферную очередь, которая часто используется SurfaceFlinger. При рендеринге на поверхность результат попадает в буфер, который отправляется потребителю. API-интерфейсы Canvas предоставляют программную реализацию (с поддержкой аппаратного ускорения) для рисования непосредственно на поверхности (низкоуровневая альтернатива OpenGL ES). Все, что связано с представлением, включает в себя SurfaceHolder, API которого позволяют получать и устанавливать параметры поверхности, такие как размер и формат.
- EGLSurface и OpenGL ES . OpenGL ES (GLES) определяет API рендеринга графики, предназначенный для комбинирования с EGL , библиотекой, которая может создавать окна и получать к ним доступ через операционную систему (для рисования текстурированных многоугольников используйте вызовы GLES; для вывода рендеринга на экран используйте вызовы EGL). ). На этой странице также описан ANativeWindow, эквивалент C/C++ класса Java Surface, используемый для создания поверхности окна EGL из машинного кода.
- Вулкан . Vulkan — это кроссплатформенный API с низкими издержками для высокопроизводительной 3D-графики. Как и OpenGL ES, Vulkan предоставляет инструменты для создания высококачественной графики в реальном времени в приложениях. Преимущества Vulkan включают снижение нагрузки на ЦП и поддержку двоичного промежуточного языка SPIR-V .
Компоненты высокого уровня
- Поверхностный вид и GLSurfaceView . SurfaceView объединяет поверхность и вид. Компоненты представления SurfaceView составляются с помощью SurfaceFlinger (а не приложения), что позволяет выполнять рендеринг из отдельного потока/процесса и изолировать от рендеринга пользовательского интерфейса приложения. GLSurfaceView предоставляет вспомогательные классы для управления контекстами EGL, межпоточной связью и взаимодействием с жизненным циклом активности (но это не обязательно для использования GLES).
- Текстура поверхности . SurfaceTexture объединяет поверхность и текстуру GLES для создания BufferQueue, потребителем которого является ваше приложение. Когда производитель ставит в очередь новый буфер, он уведомляет ваше приложение, которое, в свою очередь, освобождает ранее удерживаемый буфер, получает новый буфер из очереди и выполняет вызовы EGL, чтобы сделать буфер доступным для GLES в качестве внешней текстуры. В Android 7.0 добавлена поддержка безопасного воспроизведения текстурного видео, позволяющая выполнять постобработку защищенного видеоконтента на графическом процессоре.
- Просмотр текстуры . TextureView сочетает в себе представление с SurfaceTexture. TextureView оборачивает SurfaceTexture и берет на себя ответственность за ответ на обратные вызовы и получение новых буферов. При рисовании TextView использует содержимое последнего полученного буфера в качестве источника данных, осуществляя рендеринг везде и в любом месте, где состояние представления указывает на это. Композиция представления всегда выполняется с помощью GLES, а это означает, что обновления содержимого могут также привести к перерисовке других элементов представления.