Las capas y las pantallas son dos primitivas que representan el trabajo de composición y las interacciones con el hardware de la pantalla.
Capas
Una capa es la unidad de composición más importante. Una capa es un
combinación de una superficie y una instancia de
SurfaceControl
Cada capa tiene un conjunto de propiedades
y definir cómo interactúa con otras capas. Las propiedades de la capa se describen en la tabla a continuación.
Propiedad | Descripción |
---|---|
Posicional | Define dónde aparece la capa en la pantalla. Incluye información como las posiciones de los bordes de una capa y su orden en Z en relación con otras capas (si debe estar delante o detrás de otras capas) otras capas). |
Contenido | Define cómo se debe presentar el contenido que se muestra en la capa dentro de los límites definidos por las propiedades de posición. Incluye información como como recorte (para expandir una parte del contenido y llenar los límites de la capa) y transform (para mostrar contenido rotado o invertido). |
Composición | Define cómo se debe componer la capa con otras capas. Incluye información como el modo de fusión y un valor alfa en toda la capa para alfa composición. |
Optimización | Proporciona información que no es estrictamente necesaria para combinar correctamente la capa, pero que el dispositivo Hardware Composer (HWC) puede usar para optimizar la forma en que realiza la composición. Incluye información como el región visible de la capa y qué parte de la capa se desde el marco anterior. |
Displays
Una pantalla es otra unidad de composición importante. Un sistema puede tienen varias pantallas y se pueden agregar o quitar pantallas durante las operaciones normales del sistema. Las pantallas son agregar o quitar a pedido del HWC o cuando el framework lo solicite. Las pantallas de solicitudes de dispositivos HWC deben agregarse o eliminarse cuando se crea la pantalla está conectada o desconectada del dispositivo, lo que se denomina Hotspot. Los clientes solicitan pantallas virtuales cuyo contenido se renderizan en un búfer fuera de la pantalla y no en una pantalla física.
Pantallas virtuales
SurfaceFlinger admite una pantalla interna (integrada en el teléfono o la tablet), pantallas externas (como una televisión conectada a través de HDMI) y una o más pantallas virtuales que ponen a disposición del sistema la salida compuesta. Las pantallas virtuales pueden usarse para grabar la pantalla o enviarla a través de una red. Se generaron los marcos de una pantalla virtual se escriben en una BufferQueue.
Las pantallas virtuales pueden compartir el mismo conjunto de capas que la pantalla principal (la pila de capas) o tener su propio conjunto. No hay VSYNC para una pantalla virtual, por lo que la VSYNC de la pantalla interna activa la composición para todas las pantallas.
En las implementaciones de HWC que las admiten, las pantallas virtuales se pueden combinar con OpenGL ES (GLES), HWC o ambos. En implementaciones no compatibles, las pantallas virtuales siempre se componen con ¡GLES!
Caso de éxito: Screenrecord
El comando screenrecord
permite al usuario grabar todo lo que aparece en la pantalla como un archivo .mp4
en el disco. Para implementar esto, el sistema recibe fotogramas compuestos de SurfaceFlinger, los escribe en el codificador de video y, luego, escribe los datos de video codificados en un archivo. Los códecs de video se administran mediante un proceso independiente (mediaserver
), por lo que los búferes de gráficos grandes deben moverse por el sistema. Para que sea más desafiante, el objetivo es grabar videos a 60 fps con resolución completa. La clave para hacer este trabajo de forma eficiente es BufferQueue.
La clase MediaCodec
permite que una app proporcione datos como bytes sin procesar en búferes o a través de una superficie. Cuando screenrecord
solicita acceso a un video
codificador, el proceso mediaserver
crea una BufferQueue, que conecta
al consumidor y, luego, pasa el lado del productor de vuelta
screenrecord
como una superficie
Luego, la utilidad screenrecord
le solicita a SurfaceFlinger que cree un
una pantalla virtual que duplica la pantalla principal (es decir, tiene las mismas
capas) y lo dirige para que envíe a la superficie los resultados provenientes de la
mediaserver
proceso. En este caso, SurfaceFlinger es el productor de búferes en lugar del consumidor.
Una vez completada la configuración, screenrecord
se activa cuando aparecen los datos codificados. A medida que las apps se dibujan, sus búferes viajan a SurfaceFlinger,
que los compone en un solo búfer que se envía directamente al video
en el proceso mediaserver
. El proceso screenrecord
nunca ve los fotogramas completos. A nivel interno, el
El proceso mediaserver
tiene su propia forma de mover los búferes
también pasa datos por controlador, lo que minimiza la sobrecarga.
Caso de éxito: Simula pantallas secundarias
WindowManager puede pedirle a SurfaceFlinger que cree una capa visible para la que SurfaceFlinger actúa como consumidor de BufferQueue. También es posible pedirle a SurfaceFlinger que cree una pantalla virtual, para la cual SurfaceFlinger actúa como productor de BufferQueue.
Si conectas una pantalla virtual a una capa visible, se crea un bucle cerrado.
donde la pantalla compuesta aparece en una ventana. Esa ventana ahora forma parte del resultado compuesto, por lo que, en la próxima actualización, la imagen compuesta dentro de la ventana también mostrará el contenido de la ventana. Para ver esto en acción, habilita
Opciones para desarrolladores en Configuración, selecciona
Simula pantallas secundarias y habilita una ventana. Para ver
pantallas secundarias en acción; usa screenrecord
para capturar el acto
de habilitar la pantalla y, luego, reproducirla fotograma por fotograma.