Google se compromete a impulsar la igualdad racial para las comunidades afrodescendientes. Obtén información al respecto.

BufferQueue y Gralloc

La clase BufferQueue conecta componentes que generan búferes de datos gráficos ( productores ) con componentes que aceptan los datos para su visualización o procesamiento posterior ( consumidores ). Casi todo lo que mueve búferes de datos gráficos a través del sistema se basa en BufferQueue.

El asignador de memoria de Gralloc realiza asignaciones de búfer y se implementa a través de dos interfaces HIDL específicas del proveedor (consulte hardware/interfaces/graphics/allocator/ y hardware/interfaces/graphics/mapper/ ). La función allocate() toma los argumentos esperados (ancho, alto, formato de píxel) así como un conjunto de indicadores de uso.

Productores y consumidores de BufferQueue

Los consumidores crean y poseen la estructura de datos de BufferQueue y pueden existir en procesos diferentes a los de sus productores. Cuando un productor necesita un búfer, solicita un búfer libre de BufferQueue llamando a dequeueBuffer() , especificando el ancho, alto, formato de píxel y marcas de dequeueBuffer() los búferes. Luego, el productor llena el búfer y lo devuelve a la cola llamando a queueBuffer() . A continuación, el consumidor adquiere el búfer con acquireBuffer() y hace uso del contenido del búfer. Cuando el consumidor releaseBuffer() , devuelve el búfer a la cola llamando a releaseBuffer() . El marco de sincronización controla cómo se mueven los búferes a través de la canalización de gráficos de Android.

Algunas características de BufferQueue, como el número máximo de búferes que puede contener, las determinan conjuntamente el productor y el consumidor. Sin embargo, BufferQueue asigna búferes cuando los necesita. Los tampones se conservan a menos que cambien las características; por ejemplo, si un productor solicita búferes con un tamaño diferente, los búferes antiguos se liberan y se asignan nuevos búferes a pedido.

BufferQueue nunca copia el contenido del búfer, ya que mover esa cantidad de datos es ineficaz. En cambio, los búferes siempre se pasan por un identificador.

Seguimiento de BufferQueue con Systrace

Para comprender cómo se mueven los búferes de gráficos, use Systrace , una herramienta que registra la actividad del dispositivo durante un período corto de tiempo. El código de gráficos a nivel del sistema está bien instrumentado, al igual que gran parte del código del marco de la aplicación relevante.

Para usar Systrace, habilite las gfx , view y sched . Los objetos BufferQueue se muestran en el seguimiento. Por ejemplo, si realiza un seguimiento mientras se está ejecutando el video de reproducción de Grafika (SurfaceView) , la fila etiquetada SurfaceView le indica cuántos búferes se pusieron en cola en un momento dado.

El valor aumenta mientras la aplicación está activa, lo que activa la representación de fotogramas por el decodificador MediaCodec. El valor disminuye mientras SurfaceFlinger está funcionando y consumiendo búferes. Cuando se muestra un video a 30 fps, el valor de la cola varía de 0 a 1 porque la pantalla de ~ 60 fps puede seguir el ritmo de la fuente. SurfaceFlinger se activa solo cuando hay trabajo por hacer, no 60 veces por segundo. El sistema intenta evitar el trabajo y deshabilita VSYNC si nada actualiza la pantalla.

Si cambia al video de reproducción de Grafika (TextureView) y toma un nuevo trazo, verá una fila etiquetada como com.android.grafika / com.android.grafika.PlayMovieActivity . Esta es la capa principal de la interfaz de usuario, que es otra BufferQueue. Debido a que TextureView se procesa en la capa de la interfaz de usuario en lugar de en una capa separada, todas las actualizaciones impulsadas por video se muestran aquí.

Gralloc

El asignador de Gralloc HAL hardware/libhardware/include/hardware/gralloc.h realiza asignaciones de búfer a través de indicadores de uso. Las banderas de uso incluyen atributos como:

  • Con qué frecuencia se accederá a la memoria desde el software (CPU)
  • Con qué frecuencia se accederá a la memoria desde el hardware (GPU)
  • Si la memoria se utilizará como una textura OpenGL ES (GLES)
  • Si la memoria será utilizada por un codificador de video

Por ejemplo, si el formato de búfer de un productor especifica RGBA_8888 píxeles, y el productor indica que se accederá al búfer desde el software (lo que significa que una aplicación tocará píxeles en la CPU), Gralloc crea un búfer con 4 bytes por píxel en orden RGBA. Si, en cambio, un productor especifica que se accederá a su búfer solo desde el hardware y como una textura GLES, Gralloc puede hacer cualquier cosa que el controlador GLES desee, como ordenar BGRA, diseños swizzled no lineales y formatos de color alternativos. Permitir que el hardware utilice su formato preferido puede mejorar el rendimiento.

Algunos valores no se pueden combinar en determinadas plataformas. Por ejemplo, la bandera del codificador de video puede requerir píxeles YUV, por lo que la adición de acceso al software y la especificación de RGBA_8888 fallan.

El identificador devuelto por Gralloc se puede pasar entre procesos a través de Binder.

Búferes protegidos

El indicador de uso de GRALLOC_USAGE_PROTECTED permite que el búfer de gráficos se muestre solo a través de una ruta protegida por hardware. Estos planos de superposición son la única forma de mostrar contenido DRM (SurfaceFlinger o el controlador OpenGL ES no pueden acceder a búferes protegidos con DRM).

El video protegido por DRM solo se puede presentar en un plano de superposición. Los reproductores de video que admiten contenido protegido deben implementarse con SurfaceView. El software que se ejecuta en hardware no protegido no puede leer ni escribir en el búfer; Las rutas protegidas por hardware deben aparecer en la superposición de Hardware Composer (es decir, los videos protegidos desaparecen de la pantalla si Hardware Composer cambia a la composición OpenGL ES).

Para obtener detalles sobre el contenido protegido, consulte DRM .