Lo que todo desarrollador debe saber sobre las superficies, SurfaceHolder, EGLSurface, SurfaceView, GLSurfaceView, SurfaceTexture, TextureView, SurfaceFlinger y Vulkan.
En esta página, se describen los elementos esenciales de la arquitectura de gráficos a nivel del sistema de Android y cómo los usan el framework de la app y el sistema multimedia. El enfoque se centra en cómo los búferes de datos gráficos se mueven por el sistema. Si alguna vez te preguntaste por qué SurfaceView y TextureView se comportan de la manera en que lo hacen, o cómo interactúan las superficies y EGLSurface, estás en el lugar correcto.
Se supone que tienes cierta familiaridad con los dispositivos Android y el desarrollo de apps. No necesitas conocimientos detallados del framework de la app y se mencionan muy pocas llamadas a la API, pero el material no se superpone con otra documentación pública. El objetivo es proporcionar detalles sobre los eventos importantes involucrados en la renderización de un fotograma para la salida y ayudarte a tomar decisiones fundamentadas cuando diseñes una app. Para lograrlo, este documento funciona de abajo hacia arriba, describiendo cómo funcionan las clases de IU en lugar de cómo se pueden usar.
En esta sección, se incluyen varias páginas que abarcan todo, desde material de referencia hasta detalles del HAL y casos de uso. Comienza con una explicación de los búferes de gráficos de Android, describe el mecanismo de composición y visualización, y luego continúa con los mecanismos de nivel superior que proporcionan datos al compositor. Te recomendamos que leas las páginas en el siguiente orden en lugar de saltarte un tema que te parezca interesante.
Componentes de bajo nivel
- BufferQueue y gralloc. BufferQueue conecta algo que genera búferes de datos gráficos (el productor) con algo que acepta los datos para su visualización o procesamiento adicional (el consumidor). Las asignaciones de búfer se realizan a través del asignador de memoria gralloc implementado a través de una interfaz HAL específica del proveedor.
- SurfaceFlinger, Hardware Composer y pantallas virtuales. SurfaceFlinger acepta búferes de datos de varias fuentes, los compone y los envía a la pantalla. El HAL de Hardware Composer (HWC) determina la forma más eficiente de componer búferes con el hardware disponible, y las pantallas virtuales hacen que la salida compuesta esté disponible dentro del sistema (grabación de la pantalla o envío de la pantalla a través de una red).
- Surface, Canvas y SurfaceHolder. Una superficie produce una cola de búfer que SurfaceFlinger suele consumir. Cuando se renderiza en una superficie, el resultado termina en un búfer que se envía al consumidor. Las APIs de Canvas proporcionan una implementación de software (con compatibilidad con la aceleración por hardware) para dibujar directamente en una superficie (alternativa de bajo nivel a OpenGL ES). Todo lo que tiene que ver con una vista involucra un SurfaceHolder, cuyas APIs permiten obtener y establecer parámetros de superficie, como el tamaño y el formato.
- EGLSurface y OpenGL ES OpenGL ES (GLES) define una API de renderización de gráficos diseñada para combinarse con EGL, una biblioteca que puede crear ventanas y acceder a ellas a través del sistema operativo (para dibujar polígonos texturizados, usa llamadas a GLES; para colocar la renderización en la pantalla, usa llamadas a EGL). En esta página, también se aborda ANativeWindow, el equivalente en C/C++ de la clase Surface de Java que se usa para crear una superficie de ventana de EGL a partir de código nativo.
- Vulkan. Vulkan es una API multiplataforma de baja sobrecarga para gráficos 3D de alto rendimiento. Al igual que OpenGL ES, Vulkan proporciona herramientas para crear gráficos de alta calidad en tiempo real en las apps. Entre las ventajas de Vulkan, se incluyen la reducción de la sobrecarga de la CPU y la compatibilidad con el lenguaje intermedio binario SPIR-V.
Componentes de alto nivel
- SurfaceView y GLSurfaceView. SurfaceView combina una superficie y una vista. SurfaceFlinger compone los componentes de la vista de SurfaceView (y no la app), lo que permite la renderización desde un subproceso o proceso independiente y el aislamiento de la renderización de la IU de la app. GLSurfaceView proporciona clases de ayuda para administrar contextos de EGL, comunicación entre subprocesos e interacción con el ciclo de vida de la actividad (pero no es necesario usar GLES).
- SurfaceTexture. SurfaceTexture combina una superficie y una textura de GLES para crear un BufferQueue para el que tu app es el consumidor. Cuando un productor pone en cola un búfer nuevo, notifica a tu app, que a su vez libera el búfer que tenía anteriormente, adquiere el búfer nuevo de la cola y realiza llamadas a EGL para que el búfer esté disponible para GLES como una textura externa. Android 7.0 agregó compatibilidad con la reproducción de video de texturas seguras, lo que permite el procesamiento posterior en la GPU del contenido de video protegido.
- TextureView. TextureView combina una vista con un SurfaceTexture. TextureView encapsula un SurfaceTexture y se encarga de responder a las devoluciones de llamada y adquirir nuevos búferes. Cuando se dibuja, TextureView usa el contenido del búfer recibido más recientemente como fuente de datos, y renderiza donde y como lo indica el estado de la vista. La composición de la vista siempre se realiza con GLES, lo que significa que las actualizaciones del contenido también pueden hacer que se vuelvan a dibujar otros elementos de la vista.