Графика

Значок Android Graphics HAL

Фреймворк Android предлагает разнообразные API для рендеринга графики в 2D и 3D, взаимодействующие с реализациями графических драйверов производителей, поэтому важно хорошо понимать, как эти API работают на более высоком уровне. На этой странице описывается уровень абстракции графического оборудования (HAL), на котором построены эти драйверы. Прежде чем продолжить чтение этого раздела, ознакомьтесь со следующими терминами:

холст (общий термин), Canvas (элемент API)
Холст — это поверхность для рисования, которая обрабатывает композицию битов на основе растрового изображения или объекта Surface . Класс Canvas содержит методы для стандартного компьютерного рисования растровых изображений, линий, окружностей, прямоугольников, текста и так далее и привязан к растровому изображению или поверхности. Холст — это самый простой и удобный способ рисования двумерных объектов на экране. Базовым классом является Canvas .
рисуемый
Рисуемый объект — это скомпилированный визуальный ресурс, который можно использовать в качестве фона, заголовка или другой части экрана. Рисуемый объект обычно загружается в другой элемент пользовательского интерфейса, например, в качестве фонового изображения. Рисуемый объект не может получать события, но назначает различные другие свойства, такие как состояние и планирование, для включения подклассов, таких как объекты анимации или библиотеки изображений. Многие рисуемые объекты загружаются из файлов ресурсов рисования — XML или растровых файлов, описывающих изображение. Рисуемые ресурсы компилируются в подклассы android.graphics.drawable . Подробнее о рисуемых объектах и ​​других ресурсах см. в разделе Обзор ресурсов приложения .
ресурс макета
Ресурс макета — это XML-файл, описывающий макет экрана активности. Подробнее см. в разделе Ресурс макета .
девять патчей (9-патч, NinePatch)
Nine-patch — это растровый ресурс изменяемого размера, который можно использовать в качестве фона или других изображений на устройстве. Подробнее см. в разделе Nine-patch .
OpenGL ES
OpenGL ES — это кроссплатформенный API для рендеринга 2D- и 3D-графики. Android предоставляет библиотеки OpenGL ES для аппаратного ускорения 3D-рендеринга. Для 2D-рендеринга более простым вариантом является холст. OpenGL ES доступен в Android Native Development Kit (NDK) . Пакеты android.opengl и javax.microedition.khronos.opengles предоставляют функциональность OpenGL ES.
поверхность (общий термин), Surface (элемент API)
Поверхность представляет собой блок памяти, который компонуется на экране. Поверхность содержит холст для рисования и предоставляет различные вспомогательные методы для рисования слоёв и изменения размера объекта Surface . Используйте класс SurfaceView вместо класса Surface напрямую.
вид поверхности (общий термин), SurfaceView (элемент API)
Вид поверхности — это объект View , который является оболочкой для объекта Surface для отрисовки и предоставляет методы для динамического задания его размера и формата. Вид поверхности позволяет выполнять отрисовку независимо от потока пользовательского интерфейса для ресурсоёмких операций, таких как игры или предварительный просмотр камеры, но в результате потребляет больше памяти. Вид поверхности поддерживает как графику Canvas, так и графику OpenGL ES. Базовым классом для объекта SurfaceView является SurfaceView .
тема
Тема — это набор свойств, таких как размер текста и цвет фона, объединенных вместе для определения различных настроек отображения по умолчанию. Android предоставляет несколько стандартных тем, перечисленных в R.style и имеющих префикс Theme_ .
вид (общий термин), View (элемент API)
Вид отрисовывает прямоугольную область на экране и обрабатывает щелчки, нажатия клавиш и другие события взаимодействия. Класс View является базовым для большинства компонентов макета экрана активности или диалогового окна, таких как текстовые поля и окна. Объект View получает вызовы от своего родительского объекта (см. ViewGroup ) для отрисовки и сообщает родительскому объекту свои предпочтительные размеры и местоположение, которые могут не учитываться родителем. Подробнее см. в View .
группа представлений (общий термин), ViewGroup (элемент API)
Группа представлений объединяет набор дочерних представлений. Группа представлений отвечает за определение местоположения дочерних представлений и их допустимого размера, а также за вызов отрисовки каждого из них при необходимости. Некоторые группы представлений невидимы и предназначены только для макета, в то время как другие имеют встроенный пользовательский интерфейс, например, прокручиваемый список. Группы представлений входят в пакет android.widget , но являются расширением класса ViewGroup .
иерархия просмотра
Иерархия представлений — это структура объектов представлений и групп представлений, определяющая пользовательский интерфейс для каждого компонента приложения. Иерархия состоит из групп представлений, содержащих одно или несколько дочерних представлений или групп представлений. Вы можете получить визуальное представление иерархии представлений для отладки и оптимизации с помощью средства просмотра иерархии , входящего в состав Android SDK.
Вулкан
Vulkan — это кроссплатформенный API с низкими накладными расходами для высокопроизводительной 3D-графики.
виджет
Виджет — это один из набора полностью реализованных подклассов представления, которые отображают элементы формы и другие компоненты пользовательского интерфейса, такие как текстовое поле или всплывающее меню. Поскольку виджет полностью реализован, он обрабатывает измерения, отрисовывает себя и реагирует на события на экране. Виджеты находятся в пакете android.widget .
окно (общий термин), Window (элемент API)
В приложении Android окно — это объект, производный от абстрактного класса Window , который определяет элементы универсального окна, такие как внешний вид, текст заголовка, а также расположение и содержимое меню. Диалоговые окна и действия используют реализацию класса Window для рендеринга объекта Window . Вам не нужно реализовывать класс Window или использовать окна в вашем приложении.

Разработчики приложений выводят изображения на экран тремя способами: с помощью Canvas , OpenGL ES или Vulkan .

Графические компоненты Android

Независимо от того, какой API рендеринга используют разработчики, всё отображается на поверхности. Поверхность представляет собой сторону-производителя очереди буфера, которую часто использует SurfaceFlinger. Каждое окно, создаваемое на платформе Android, поддерживается поверхностью. Все видимые поверхности, отображаемые SurfaceFlinger, компонуются на дисплее.

На следующей диаграмме показано, как ключевые компоненты работают вместе:

компоненты рендеринга изображений

Рисунок 1. Как визуализируются поверхности.

Основные компоненты описаны в следующих разделах.

Производители потока изображений

Производителем потока изображений может быть любой источник, создающий графические буферы для использования. Примерами могут служить OpenGL ES, Canvas 2D и видеодекодеры медиасерверов.

Потребители потока изображений

Наиболее распространённым потребителем потоков изображений является SurfaceFlinger — системная служба, которая получает видимые в данный момент поверхности и компонует их на дисплее, используя информацию, предоставленную диспетчером окон. SurfaceFlinger — единственная служба, которая может изменять содержимое дисплея. SurfaceFlinger использует OpenGL и Hardware Composer (HWC) для компоновки группы поверхностей.

Другие приложения OpenGL ES также могут потреблять потоки изображений, например, приложение камеры, использующее поток изображения предварительного просмотра камеры. Приложения, не использующие OpenGL ES, также могут быть потребителями, например, класс ImageReader.

Аппаратный композитор

Аппаратная абстракция для подсистемы отображения. SurfaceFlinger может делегировать часть работы по компоновке аппаратному обеспечению (HWC), чтобы разгрузить OpenGL и графический процессор. SurfaceFlinger действует как ещё один клиент OpenGL ES. Поэтому, например, когда SurfaceFlinger активно компонует один или два буфера в третий, он использует OpenGL ES. Это делает компоновку менее энергозатратной, чем выполнение всех вычислений графическим процессором.

Hardware Composer HAL выполняет вторую половину работы и является центральной точкой для всего графического рендеринга Android. HWC должен поддерживать события, одним из которых является VSync (ещё одним — горячее подключение для поддержки HDMI по технологии plug-and-play).

Граллок

Распределитель графической памяти (Gralloc) необходим для выделения памяти, запрашиваемой производителями изображений. Подробнее см. в разделах BufferQueue и Gralloc .

Поток данных

На следующей диаграмме изображен графический конвейер Android:

поток графических данных

Рисунок 2. Графический поток данных через Android.

Объекты слева — это рендереры, создающие графические буферы, такие как домашний экран, строка состояния и системный пользовательский интерфейс. SurfaceFlinger — компоновщик, а HWC — компоновщик.

BufferQueue

BufferQueues обеспечивают связующее звено между графическими компонентами Android. Это пара очередей, которые обеспечивают постоянный цикл буферов от производителя к потребителю. После того, как производители передают свои буферы, SurfaceFlinger отвечает за компоновку всего изображения на дисплее.

Следующая диаграмма иллюстрирует процесс коммуникации BufferQueue:

Процесс связи BufferQueue

Рисунок 3. Процесс коммуникации BufferQueue.

BufferQueue содержит логику, связывающую производителей и потребителей потоков изображений. Примерами производителей изображений являются предварительные просмотры камеры, создаваемые играми HAL или OpenGL ES. Примерами потребителей изображений являются SurfaceFlinger или другое приложение, отображающее поток OpenGL ES, например, приложение камеры, отображающее видоискатель камеры.

BufferQueue — это структура данных, которая объединяет буферный пул с очередью и использует межпроцессное взаимодействие (IPC) Binder для передачи буферов между процессами. Интерфейс производителя, или то, что вы передаёте тому, кто хочет сгенерировать графические буферы, — это IGraphicBufferProducer (часть SurfaceTexture ). BufferQueue часто используется для рендеринга на Surface и использования с помощью GL Consumer, среди прочих задач.

BufferQueue может работать в трех различных режимах:

синхронно-подобный режим
По умолчанию BufferQueue работает в синхронном режиме, в котором каждый буфер, поступающий от производителя, отправляется потребителю. В этом режиме ни один буфер не удаляется. Если производитель слишком быстр и создаёт буферы быстрее, чем они опустошаются, он блокируется и ждёт освобождения буферов.
неблокируемый режим
BufferQueue также может работать в неблокирующем режиме, генерируя ошибку вместо ожидания буфера в таких случаях. В этом режиме буферы никогда не сбрасываются. Это полезно для предотвращения потенциальных взаимоблокировок в прикладном программном обеспечении, которое может не понимать сложные зависимости графического фреймворка.
режим сброса
BufferQueue можно настроить так, чтобы старые буферы удалялись, а не генерировались ошибки или ожидалось. Например, если выполняется рендеринг GL в виде текстуры и отрисовка выполняется максимально быстро, буферы необходимо удалять.

Для выполнения большей части этой работы SurfaceFlinger выступает в роли ещё одного клиента OpenGL ES. Например, когда SurfaceFlinger активно компонует один или два буфера в третий, он использует OpenGL ES.

Вторую половину работы выполняет Hardware Composer HAL. Этот HAL служит центральной точкой для всего графического рендеринга Android.