Implementa la HAL del compositor de hardware

Las capas compuestas de la HAL del compositor de hardware (HWC) recibidas de SurfaceFlinger, lo que reduce la cantidad de composición de OpenGL ES (GLES) y la GPU.

El HWC abstrae objetos, como superposiciones y blitters 2D, para componer y se comunica con un hardware de composición de ventanas especializado para ventanas compuestas. Usar HWC para crear ventanas compuestas en lugar de tener El compuesto SurfaceFlinger con la GPU. La mayoría de las GPU no están optimizadas composición, y cuando la GPU compone capas de SurfaceFlinger, las apps no pueden usar la GPU para su propia renderización.

Las implementaciones de HWC deben admitir lo siguiente:

  • Al menos cuatro superposiciones:
    • Barra de estado
    • Barra del sistema
    • App
    • Fondo de pantalla/fondo
  • Capas que son más grandes que la pantalla (por ejemplo, un fondo de pantalla)
  • Combinación alfa por píxel premultiplicada en simultáneo y por plano combinación alfa
  • Ruta de acceso de hardware para la reproducción de video protegida
  • Orden de empaquetado RGBA, formatos YUV, mosaicos, swizzling y stride propiedades

Para implementar el HWC, haz lo siguiente:

  1. Implementa un HWC no operativo y envía todo el trabajo de composición a ¡GLES!
  2. Implementa un algoritmo para delegar la composición al HWC de forma incremental. Por ejemplo, delega solo las primeras tres o cuatro superficies a la superposición. el hardware del HWC.
  3. Optimiza el HWC. Esto puede incluir:
    • Seleccionar superficies que maximicen la carga quitada de la GPU y enviándolos al HWC.
    • Detecta si se actualiza la pantalla. Si no es así, delega la composición a GLES en lugar de HWC para ahorrar energía. Cuando aparezca la pantalla y continúa descargando la composición al HWC.
    • Preparación para casos de uso comunes, como los siguientes:
      • La pantalla principal, que incluye la barra de estado, la barra del sistema y la app la ventana y los fondos de pantalla animados
      • Juegos en pantalla completa en modo vertical y horizontal
      • Video en pantalla completa con subtítulos y reproducción Control
      • Reproducción de video protegida
      • Multiventana con pantalla dividida

Primitivas de HWC

El HWC proporciona dos primitivas, capas y pantallas, para representar el trabajo de composición y su interacción con el hardware de visualización. El HWC también proporciona control sobre VSYNC y una devolución de llamada a SurfaceFlinger para notificarlo cuando ocurre un evento VSYNC.

Interfaz de HIDL

Android 8.0 y las versiones posteriores usan un HIDL llamada Composer HAL para IPC vinculante entre HWC y SurfaceFlinger. La HAL de Composer reemplaza al interfaz hwcomposer2.h heredada. Si los proveedores proporcionan una HAL de Composer del HWC, la HAL del compositor acepta directamente las llamadas HIDL de SurfaceFlinger. Si los proveedores proporcionan una implementación heredada del HWC, Composer La HAL carga punteros de función de hwcomposer2.h, reenviar llamadas HIDL a llamadas de puntero de función

El HWC proporciona funciones para determinar las propiedades de una pantalla determinada. a para alternar entre diferentes configuraciones de pantalla (como 4K o 1080p) resolución) y los modos de color (como color nativo o sRGB verdadero) y para encenderlo encender o apagar la pantalla, o bien activar el modo de bajo consumo (si es compatible).

Punteros de función

Si los proveedores implementan la HAL de Composer directamente, SurfaceFlinger llama a sus funciones a través de la IPC de HIDL. Por ejemplo, para crear una capa, SurfaceFlinger llama createLayer() en la HAL del compositor

Si los proveedores implementan la interfaz de hwcomposer2.h, la HAL de Composer llamadas a punteros de función hwcomposer2.h. En hwcomposer2.h comentarios, Las funciones de la interfaz de HWC son a los que se hace referencia con nombres lowerCamelCase que no existen en la interfaz. como campos con nombre. Casi todas las funciones se cargan mediante la solicitud de un puntero de función con getFunction proporcionado por hwc2_device_t Por ejemplo, la función createLayer es un puntero de función de tipo HWC2_PFN_CREATE_LAYER, que es se muestra cuando el valor enumerado HWC2_FUNCTION_CREATE_LAYER es se pasó a getFunction.

Para obtener documentación detallada sobre las funciones de la HAL de Composer y la transferencia de funciones de HWC consulta composer. Para obtener documentación detallada Punteros de la función HWC, consulta la hwcomposer2.h

Controladores de capa y visualización

Las capas y las pantallas se manipulan con controladores generados por HWC. Los controladores son opacos para SurfaceFlinger.

Cuando SurfaceFlinger crea una capa nueva, llama a createLayer, que devuelve el tipo Layer para valores directos o hwc2_layer_t para las implementaciones de transferencia. Cuándo SurfaceFlinger modifica una propiedad de esa capa, SurfaceFlinger pasa el valor hwc2_layer_t en la función de modificación correspondiente junto con cualquier otra información necesaria para realizar la modificación. El El tipo hwc2_layer_t es lo suficientemente grande como para contener un puntero o una índice.

Las pantallas físicas se crean mediante una conexión en caliente. Cuando una pantalla física está HWC, el HWC crea un controlador y lo pasa a SurfaceFlinger a través de la devolución de llamada Hotplug. SurfaceFlinger crea las pantallas virtuales llamando a createVirtualDisplay() para solicitar una pantalla. Si el HWC admite la composición de pantalla virtual, muestra un controlador. Luego, SurfaceFlinger delega la composición de la muestra al HWC. Si el HWC no admite máquinas virtuales SurfaceFlinger crea el controlador y compone la pantalla.

Mostrar operaciones de composición

Una vez por VSYNC, SurfaceFlinger se activa si tiene contenido nuevo . Este contenido nuevo pueden ser nuevos búferes de imágenes de apps o un cambio en las propiedades de una o más capas. Cuando se usa SurfaceFlinger la activa:

  1. Controla las transacciones, si están presentes.
  2. Bloquea nuevos búferes gráficos, si están presentes.
  3. Realiza una composición nueva si el paso 1 o 2 generó un cambio. a los contenidos de la pantalla.

Para realizar una nueva composición, SurfaceFlinger crea y Destruye las capas o modifica los estados de las capas, según corresponda. También actualiza capas con su contenido actual, mediante llamadas como setLayerBuffer o setLayerColor. Una vez que todas las capas actualizado, SurfaceFlinger llama a validateDisplay, que le indica el HWC para examinar el estado de las capas y determinar cómo se modificará continuar. De forma predeterminada, SurfaceFlinger intenta configurar cada capa para que el HWC componga la capa; aunque, en algunas SurfaceFlinger compone capas a través del resguardo de la GPU.

Después de la llamada a validateDisplay, SurfaceFlinger llama a getChangedCompositionTypes para ver si el HWC desea que alguno de los tipos de composición de capas cambie antes de realizar de los datos. Para aceptar los cambios, SurfaceFlinger llama acceptDisplayChanges

Si hay capas marcadas para la composición de SurfaceFlinger, SurfaceFlinger los compone en el búfer de destino. SurfaceFlinger luego llama setClientTarget para otorgar el búfer a la pantalla de modo que la el búfer se puede mostrar en la pantalla o combinarse aún más con capas que no se marcaron para la composición de SurfaceFlinger. Si no hay capas marcadas para SurfaceFlinger, SurfaceFlinger omite el paso de composición.

Por último, SurfaceFlinger llama a presentDisplay para indicarle el HWC para completar el proceso de composición y mostrar el resultado final.

Varias pantallas

Android 10 admite varias pantallas físicas. Cuando se diseña una implementación de HWC diseñada para su uso en Android 7.0 y hay algunas restricciones que no están presentes en la definición de HWC:

  • Se supone que hay exactamente una pantalla interna. La información interna pantalla es la que informa el conector en caliente inicial durante inicio. Una vez que la pantalla interna se conecta en caliente, no se puede desconectarse.
  • Además de la pantalla interna, se puede conectar cualquier cantidad de pantallas externas durante el funcionamiento normal del dispositivo. El framework supone que todos después de la primera pantalla interna son pantallas externas, así que se agregaron pantallas internas, están incorrectamente categorizadas como Display.TYPE_HDMI en lugar de Display.TYPE_BUILT_IN

Mientras se realizan las operaciones de SurfaceFlinger descritas anteriormente por pantalla, se realizan de manera secuencial en todas las pantallas activas, incluso si se actualiza el contenido de una sola pantalla.

Por ejemplo, si se actualiza la pantalla externa, la secuencia es la siguiente:

// In Android 9 and lower:

// Update state for internal display
// Update state for external display
validateDisplay(<internal display>)
validateDisplay(<external display>)
presentDisplay(<internal display>)
presentDisplay(<external display>)

// In Android 10 and higher:

// Update state for internal display
// Update state for external display
validateInternal(<internal display>)
presentInternal(<internal display>)
validateExternal(<external display>)
presentExternal(<external display>)

Composición de la pantalla virtual

La composición de la pantalla virtual es similar a la pantalla externa de los datos. Diferencia entre la composición de la pantalla virtual y la física es que las pantallas virtuales envían resultados a un búfer de Gralloc en lugar de a la pantalla. Hardware Composer (HWC) escribe la salida en un búfer. proporciona la valla de finalización y envía el búfer a un consumidor (como el codificador de video, GPU, CPU, etc.). Las pantallas virtuales pueden usar imágenes 2D/Blitter o se superponen si la canalización de pantalla escribe en la memoria.

Modos

Cada fotograma se encuentra en uno de los tres modos después de que SurfaceFlinger llama a la Método HWC validateDisplay():

  • GLES: La GPU compone todas las capas, escribe directamente en el búfer de salida. El HWC no participa en la composición.
  • MIXED: la GPU compone algunas capas en la el búfer de fotogramas y HWC componen el búfer de fotogramas y las capas restantes, directamente en el búfer de salida.
  • HWC: HWC compone todas las capas y escribe directamente al búfer de salida.

Formato de salida

Los formatos de salida del búfer de pantalla virtual dependen de su modo:

  • Modo GLES: El controlador EGL establece el búfer de salida. en dequeueBuffer(), generalmente RGBA_8888. El consumidor debe poder aceptar el formato de salida que establece el controlador o no se puede leer el búfer.
  • Modos MIXED y HWC: Si el consumidor necesita CPU acceso, el consumidor establece el formato. De lo contrario, el formato es IMPLEMENTATION_DEFINED y Gralloc establece el mejor formato en función de las marcas de uso. Por ejemplo, Gralloc establece un formato YCbCr si el consumidor el codificador de video y HWC pueden escribir el formato con eficiencia.

Vallas de sincronización

Las vallas de sincronización son un aspecto crucial de los gráficos de Android en un sistema de archivos. Las cercas permiten que el trabajo de la CPU avance independientemente del trabajo simultáneo de la GPU. el bloqueo solo cuando hay una verdadera dependencia.

Por ejemplo, cuando una app envía un búfer que se produce en la GPU, también envía un objeto de valla de sincronización. Esta valla indica cuándo se La GPU terminó de escribir en el búfer.

El HWC requiere que la GPU termine de escribir los búferes antes de que se que se muestra. Las vallas de sincronización pasan a través de la canalización de gráficos con búferes y señala cuándo se escriben los búferes. Antes de que se muestre un búfer, el HWC comprueba si se indicó la valla de sincronización; si lo hizo, muestra el tiempo de reserva.

Para obtener más información sobre las vallas de sincronización, consulta Hardware Composer Integración.