Los objetos de superficie permiten que las aplicaciones rendericen imágenes para que se presenten en las pantallas. Las interfaces de SurfaceHolder permiten que las aplicaciones editen y controlen superficies.
Superficie
Una superficie es una interfaz para que un productor intercambie amortiguadores con un consumidor.
El BufferQueue para una superficie de visualización normalmente se configura para almacenamiento en búfer triple. Los búferes se asignan a pedido, por lo que si el productor genera búferes con la suficiente lentitud, como a 30 fps en una pantalla de 60 fps, es posible que solo haya dos búferes asignados en la cola. La asignación de búferes bajo demanda ayuda a minimizar el consumo de memoria. Puede ver un resumen de los búferes asociados con cada capa en la salida de dumpsys SurfaceFlinger
.
La mayoría de los clientes renderizan sobre superficies utilizando OpenGL ES o Vulkan . Sin embargo, algunos clientes renderizan sobre superficies utilizando un lienzo.
Representación de lienzo
La implementación del lienzo es proporcionada por Skia Graphics Library . Si desea dibujar un rectángulo, llame a la API de Canvas, que establece los bytes en un búfer de manera adecuada. Para asegurarse de que dos clientes no actualicen un búfer a la vez, o que no se escriba mientras se muestra, bloquee el búfer para acceder a él. Utilice los siguientes comandos para trabajar con candados de lienzo:
-
lockCanvas()
bloquea el búfer para renderizar en la CPU y devuelve un lienzo para usar para dibujar. -
unlockCanvasAndPost()
desbloquea el búfer y lo envía al compositor. -
lockHardwareCanvas()
bloquea el búfer para renderizar en la GPU y devuelve un lienzo para usar para dibujar.
La primera vez que el productor solicita un búfer de un BufferQueue, el búfer se asigna y se inicializa a cero. La inicialización es necesaria para evitar compartir datos sin darse cuenta entre procesos. Sin embargo, si reutiliza un búfer, el contenido anterior aún está presente. Si llama repetidamente a lockCanvas()
y unlockCanvasAndPost()
sin dibujar nada, el productor alterna entre fotogramas renderizados previamente.
El código de bloqueo/desbloqueo de superficie mantiene una referencia al búfer renderizado anteriormente. Si especifica una región sucia al bloquear la superficie, copia los píxeles no sucios del búfer anterior. SurfaceFlinger o HWC normalmente manejan el búfer; pero debido a que solo necesitamos leer del búfer, no es necesario esperar el acceso exclusivo.
Soporte de superficie
Un SurfaceHolder es una interfaz que el sistema usa para compartir la propiedad de las superficies con las aplicaciones. Algunos clientes que trabajan con superficies quieren un SurfaceHolder, porque las API para obtener y establecer parámetros de superficie se implementan a través de un SurfaceHolder. Un SurfaceView contiene un SurfaceHolder.
La mayoría de los componentes que interactúan con una vista implican un SurfaceHolder. Algunas otras API, como MediaCodec, operan en la propia superficie.