Gráficos

Icono HAL de gráficos de Android

El marco de Android ofrece una variedad de API de representación de gráficos para 2D y 3D que interactúan con las implementaciones de controladores de gráficos del fabricante, por lo que es importante tener una buena comprensión de cómo funcionan esas API en un nivel superior. Esta página presenta la capa de abstracción de hardware de gráficos (HAL) en la que se basan esos controladores. Antes de continuar con esta sección, familiarícese con los siguientes términos:

lienzo (término genérico), Canvas (elemento API)
Un lienzo es una superficie de dibujo que maneja la composición de los bits reales contra un mapa de bits o un objeto Surface . Canvas tiene métodos para el dibujo por computadora estándar de mapas de bits, líneas, círculos, rectángulos, texto, etc., y está vinculado a un mapa de bits o una superficie. Un lienzo es la forma más sencilla y sencilla de dibujar objetos 2D en la pantalla. La clase base es Canvas .
dibujable
Un dibujable es un recurso visual compilado que se puede utilizar como fondo, título u otra parte de la pantalla. Un elemento de diseño normalmente se carga en otro elemento de la interfaz de usuario, por ejemplo, como imagen de fondo. Un elemento de diseño no puede recibir eventos, pero asigna otras propiedades, como estado y programación, para habilitar subclases como objetos de animación o bibliotecas de imágenes. Muchos objetos dibujables se cargan desde archivos de recursos dibujables: archivos XML o de mapa de bits que describen la imagen. Los recursos dibujables se compilan en subclases de android.graphics.drawable . Para obtener más información sobre elementos dibujables y otros recursos, consulte Recursos .
recurso de diseño
Un recurso de diseño es un archivo XML que describe el diseño de una pantalla de actividad. Para obtener más información, consulte Recurso de diseño .
nueve parches (9 parches, NinePatch)
Un nueve parche es un recurso de mapa de bits de tamaño variable que se puede utilizar para fondos u otras imágenes en el dispositivo. Para obtener más información, consulte Nueve parches .
OpenGL ES
OpenGL ES es una API multiplataforma para renderizar gráficos 2D y 3D. Android proporciona bibliotecas OpenGL ES para renderizado 3D acelerado por hardware. Para renderizado 2D, un lienzo es la opción más sencilla. OpenGL ES está disponible en el kit de desarrollo nativo de Android (NDK) . Los paquetes android.opengl y javax.microedition.khronos.opengles exponen la funcionalidad OpenGL ES.
superficie (término genérico), Surface (elemento API)
Una superficie representa un bloque de memoria que se compone en la pantalla. Una superficie contiene un lienzo para dibujar y proporciona varios métodos auxiliares para dibujar capas y cambiar el tamaño del objeto Surface . Utilice la clase SurfaceView en lugar de la clase Surface directamente.
vista de superficie (término genérico), SurfaceView (elemento API)
Una vista de superficie es un objeto View que envuelve un objeto Surface para dibujar y expone métodos para especificar su tamaño y formato dinámicamente. Una vista de superficie proporciona una forma de dibujar independientemente del subproceso de la interfaz de usuario para operaciones que consumen muchos recursos, como juegos o vistas previas de la cámara, pero como resultado utiliza memoria adicional. Una vista de superficie admite gráficos de lienzo y OpenGL ES. La clase base para un objeto SurfaceView es SurfaceView .
tema
Un tema es un conjunto de propiedades, como el tamaño del texto y el color de fondo, agrupadas para definir varias configuraciones de visualización predeterminadas. Android proporciona algunos temas estándar, enumerados en R.style y precedidos de Theme_ .
vista (término genérico), View (elemento API)
Una vista dibuja un área rectangular en la pantalla y maneja clics, pulsaciones de teclas y otros eventos de interacción. La clase View es la clase base para la mayoría de los componentes de diseño de una actividad o pantalla de diálogo, como cuadros de texto y ventanas. Un objeto View recibe llamadas de su objeto principal (consulte ViewGroup ) para dibujarse a sí mismo e informa a su objeto principal sobre su tamaño y ubicación preferidos, que podrían no ser respetados por el padre. Para obtener más información, consulte View .
ver grupo (término genérico), ViewGroup (elemento API)
Un grupo de vistas agrupa un conjunto de vistas secundarias. El grupo de vistas es responsable de decidir dónde se ubican las vistas secundarias y qué tan grandes pueden ser, así como de llamar a cada una para que se dibuje cuando sea apropiado. Algunos grupos de vistas son invisibles y sirven únicamente para el diseño, mientras que otros tienen una interfaz de usuario intrínseca, como un cuadro de lista de desplazamiento. Los grupos de vistas están en el paquete widget , pero amplían la clase ViewGroup .
ver jerarquía
Una jerarquía de vistas es una disposición de vistas y objetos de grupo de vistas que define la interfaz de usuario para cada componente de una aplicación. La jerarquía consta de grupos de vistas que contienen una o más vistas secundarias o grupos de vistas. Puede obtener una representación visual de una jerarquía de vistas para depurar y optimizar utilizando el Visor de jerarquía que se proporciona con el SDK de Android.
vulcano
Vulkan es una API multiplataforma de bajo costo para gráficos 3D de alto rendimiento.
widget
Un widget forma parte de un conjunto de subclases de vista totalmente implementadas que representan elementos de formulario y otros componentes de la interfaz de usuario, como un cuadro de texto o un menú emergente. Debido a que un widget está completamente implementado, se encarga de medir, dibujarse y responder a los eventos de la pantalla. Los widgets están en el paquete android.widget .
ventana (término genérico), Window (elemento API)
En una aplicación de Android, una ventana es un objeto derivado de la clase abstracta Window que especifica los elementos de una ventana genérica, como la apariencia, el texto de la barra de título y la ubicación y el contenido de los menús. Los diálogos y actividades utilizan una implementación de la clase Window para representar un objeto Window . No es necesario implementar la clase Window ni usar Windows en su aplicación.

Los desarrolladores de aplicaciones dibujan imágenes en la pantalla de tres formas: con Canvas , OpenGL ES o Vulkan .

Componentes gráficos de Android

No importa qué API de renderizado utilicen los desarrolladores, todo se renderiza en una superficie. La superficie representa el lado productor de una cola de búfer que SurfaceFlinger suele consumir. Cada ventana que se crea en la plataforma Android está respaldada por una superficie. Todas las superficies visibles renderizadas se componen en la pantalla mediante SurfaceFlinger.

El siguiente diagrama muestra cómo funcionan juntos los componentes clave:

componentes de representación de imágenes

Figura 1. Cómo se renderizan las superficies.

Los componentes principales se describen a continuación:

Productores de flujo de imágenes

Un productor de flujo de imágenes puede ser cualquier cosa que produzca buffers gráficos para consumo. Los ejemplos incluyen OpenGL ES, Canvas 2D y decodificadores de video de servidor de medios.

Consumidores de flujo de imágenes

El consumidor más común de flujos de imágenes es SurfaceFlinger, el servicio del sistema que consume las superficies actualmente visibles y las compone en la pantalla utilizando la información proporcionada por el Administrador de ventanas. SurfaceFlinger es el único servicio que puede modificar el contenido de la pantalla. SurfaceFlinger utiliza OpenGL y Hardware Composer para componer un grupo de superficies.

Otras aplicaciones OpenGL ES también pueden consumir secuencias de imágenes, como la aplicación de la cámara que consume una secuencia de imágenes de vista previa de la cámara. Las aplicaciones que no son GL también pueden ser consumidores, por ejemplo, la clase ImageReader.

Compositor de hardware

La abstracción de hardware para el subsistema de visualización. SurfaceFlinger puede delegar cierto trabajo de composición al Hardware Composer para descargar el trabajo de OpenGL y la GPU. SurfaceFlinger actúa como un cliente más de OpenGL ES. Entonces, cuando SurfaceFlinger está componiendo activamente uno o dos buffers en un tercero, por ejemplo, está usando OpenGL ES. Esto hace que la composición consuma menos energía que hacer que la GPU realice todos los cálculos.

Hardware Composer HAL realiza la otra mitad del trabajo y es el punto central para toda la representación de gráficos de Android. Hardware Composer debe admitir eventos, uno de los cuales es VSYNC (otro es hotplug para compatibilidad con HDMI plug-and-play).

Gralloc

El asignador de memoria de gráficos (Gralloc) es necesario para asignar la memoria solicitada por los productores de imágenes. Para obtener más información, consulte Gralloc HAL .

Flujo de datos

Consulte el siguiente diagrama para obtener una descripción de la canalización de gráficos de Android:

flujo de datos gráficos

Figura 2. Flujo de datos gráficos a través de Android

Los objetos de la izquierda son renderizadores que producen búferes de gráficos, como la pantalla de inicio, la barra de estado y la interfaz de usuario del sistema. SurfaceFlinger es el compositor y Hardware Composer es el compositor.

Cola de búfer

BufferQueues proporciona el pegamento entre los componentes gráficos de Android. Se trata de un par de colas que median en el ciclo constante de buffers desde el productor hasta el consumidor. Una vez que los productores entregan sus buffers, SurfaceFlinger es responsable de componer todo en la pantalla.

Consulte el siguiente diagrama para conocer el proceso de comunicación de BufferQueue.

Proceso de comunicación BufferQueue

Figura 3. Proceso de comunicación BufferQueue

BufferQueue contiene la lógica que une a los productores y consumidores de flujos de imágenes. Algunos ejemplos de productores de imágenes son las vistas previas de cámara producidas por la cámara HAL o los juegos OpenGL ES. Algunos ejemplos de consumidores de imágenes son SurfaceFlinger u otra aplicación que muestra una transmisión OpenGL ES, como la aplicación de la cámara que muestra el visor de la cámara.

BufferQueue es una estructura de datos que combina un grupo de búfer con una cola y utiliza Binder IPC para pasar búfer entre procesos. La interfaz del productor, o lo que le pasa a alguien que quiere generar buffers gráficos, es IGraphicBufferProducer (parte de SurfaceTexture ). BufferQueue se usa a menudo para renderizar en una superficie y consumir con un consumidor GL, entre otras tareas.

BufferQueue puede funcionar en tres modos diferentes:

Modo síncrono : BufferQueue funciona de forma predeterminada en un modo síncrono, en el que cada búfer que ingresa desde el productor sale hacia el consumidor. En este modo nunca se descarta ningún buffer. Y si el productor es demasiado rápido y crea buffers más rápido de lo que se agotan, bloqueará y esperará a que se liberen buffers.

Modo sin bloqueo : BufferQueue también puede funcionar en modo sin bloqueo donde genera un error en lugar de esperar un búfer en esos casos. En este modo tampoco se descarta ningún buffer. Esto es útil para evitar posibles bloqueos en el software de la aplicación que puede no comprender las complejas dependencias del marco de gráficos.

Modo de descarte : finalmente, BufferQueue se puede configurar para descartar búferes antiguos en lugar de generar errores o esperar. Por ejemplo, si se realiza el renderizado GL en una vista de textura y se dibuja lo más rápido posible, se deben eliminar los buffers.

Para realizar la mayor parte de este trabajo, SurfaceFlinger actúa como un cliente OpenGL ES más. Entonces, cuando SurfaceFlinger está componiendo activamente uno o dos buffers en un tercero, por ejemplo, está usando OpenGL ES.

El Hardware Composer HAL realiza la otra mitad del trabajo. Este HAL actúa como el punto central para toda la representación de gráficos de Android.