Red de conocimiento informático - Computadora portátil - Comprensión de la señal VSYNC en Android

Comprensión de la señal VSYNC en Android

En esta serie de temas sobre optimización de la interfaz de usuario, hablemos sobre el conocimiento relacionado con la representación de la interfaz de usuario, que involucra principalmente dos partes: conocimientos previos sobre la representación de la interfaz de usuario y cómo optimizar la representación de la interfaz de usuario.

"¿Qué hace exactamente setContentView() en el proceso de dibujo de Vista? 》

"Ver proceso de dibujo: el proceso de agregar DecorView a la ventana"

"Trilogía de actividades en profundidad (3) Ver proceso de dibujo"

" Android Análisis completo de LayoutInflater》

《¿Qué necesitas saber sobre el renderizado? 》

《Análisis detallado de Android Choreographer》

《Cómo optimizar la representación de la interfaz de usuario en Android (Parte 1)》

《Cómo optimizar la representación de la interfaz de usuario en Android (Parte 2) 》

La optimización es infinita. Google anunció el Proyecto Butter en la conferencia I/O de 2012 y lanzó oficialmente este mecanismo en Android 4.1.

Project Butter consta principalmente de dos componentes: uno es VSYNC y el otro es Triple Buffering.

También fue a partir de esta época que se resolvió eficazmente el problema de fluidez de la interfaz de usuario que afectaba gravemente la reputación de Android. Hoy hablaremos sobre los principios de funcionamiento de estos dos componentes, pero antes de comprenderlos, debemos analizar los otros dos conceptos involucrados:

Indica que la pantalla se actualiza en un segundo. veces, la frecuencia de actualización depende de los parámetros fijos del hardware, la unidad es HZ (Hz). Por ejemplo, el común de 60 Hz, que actualiza 60 veces por segundo.

Escaneado progresivo

El monitor no muestra la imagen en pantalla de una vez, sino que la escanea y muestra progresivamente de izquierda a derecha y de arriba a abajo, pero este proceso es rápido El cambio no puede ser detectado por el ojo humano. Tomando como ejemplo una pantalla con una frecuencia de actualización de 60 Hz, es decir, 1000/60 ≈ 16 ms.

Representa el número de fotogramas que dibuja la GPU en un segundo. Por ejemplo, las películas usan 24 fps y los sistemas Android usan 60 fps, lo que significa que se dibujan 30/60 fotogramas en un segundo. Para obtener más información, consulte "Por qué 60 fps".

Ahora, la frecuencia de actualización y la velocidad de fotogramas deben trabajar juntas para que el contenido gráfico aparezca en la pantalla. La GPU obtendrá los datos gráficos para dibujar y luego el hardware es responsable de presentar el contenido de la imagen. a la pantalla. Este proceso sucede una y otra vez durante el ciclo de vida de la aplicación.

Desafortunadamente, la frecuencia de actualización y la frecuencia de cuadros no siempre permanecen relativamente sincronizadas. Si su frecuencia de cuadros es en realidad más rápida que la frecuencia de actualización, por ejemplo, la frecuencia de cuadros es de 120 fps y la frecuencia de actualización del monitor es de 60. Hz. En este punto se producirán algunos problemas visuales.

Dado que el monitor extrae la imagen de izquierda a derecha y de arriba a abajo, este proceso tarda 16 ms (1000/60). Cuando la GPU utiliza un área de memoria para escribir datos de fotograma, se inicia un nuevo fotograma desde el. arriba, sobrescribe el fotograma anterior y genera una línea de contenido inmediatamente. Cuando la pantalla se actualiza, no conoce el estado del búfer de imagen, por lo que los fotogramas que toma de la GPU no son datos completos. Es decir, tiene la mitad del fotograma anterior y la mitad del fotograma actual. Esta situación se denomina desgarro de pantalla.

La solución a este problema es el doble buffer, donde tanto la GPU como el monitor tienen sus propios buffers de trabajo. La GPU siempre escribe un cuadro completo de datos de dibujo en el Back Buffer, mientras que el monitor usa el Frame Buffer. Cuando la pantalla se actualiza, el Frame Buffer no cambia. Back Buffer copia los datos al Frame Buffer según la actualización de la pantalla, que es donde entra en juego VSYNC.

Antes de Android 4.1, Android utilizaba un mecanismo de doble buffer. ¿Cómo entenderlo? En términos generales, las Vistas en la misma Jerarquía de Vistas utilizarán una Ventana, es decir, una Superficie.

Cada Surface tendrá una cola de caché BufferQueue, pero esta cola será administrada por SurfaceFlinger e interactuará con la capa de aplicación de la aplicación a través de una memoria compartida anónima.

Todo el proceso es el siguiente:

Android siempre ha usado VSYNC para evitar que la pantalla se rompa. Para Android 4.0, es posible que la CPU no tenga tiempo para procesar el dibujo de la interfaz de usuario porque está ocupada. otras cosas. Entonces, a partir de 4.1, VSYNC va un paso más allá: el pulso VSYNC ahora se usa para iniciar todo el procesamiento del siguiente cuadro.

VSYNC es similar a una interrupción de reloj. Cada vez que se recibe una interrupción VSYNC, la CPU preparará inmediatamente los datos del búfer. Dado que la frecuencia de actualización de la mayoría de los dispositivos de visualización es de 60 Hz (se actualiza 60 veces por segundo). es decir, un marco de datos El trabajo de preparación debe completarse en 16 ms (1000/60≈16).

De esta manera, la aplicación siempre comienza a dibujar en el límite VSYNC y SurfaceFlinger siempre compone en el límite VSYNC. Esto elimina la tartamudez y mejora la presentación visual de los gráficos.

Si comprende el principio del mecanismo de doble buffer, es muy fácil entender qué es el triple buffer. Si solo hay dos búferes de búfer gráfico A y B, si el proceso de dibujo de CPU/GPU es largo y excede un período de señal VSYNC, debido a que los datos en el búfer B aún no se han preparado, el contenido del búfer A solo puede continuar siendo mostrado, de modo que los buffers A y B estén ocupados por el dispositivo de visualización y la GPU respectivamente, y la CPU no pueda preparar los datos para el siguiente fotograma.

Si se proporciona otro búfer, la CPU, la GPU y el dispositivo de visualización pueden usar sus propios búfer para funcionar sin afectarse entre sí. En pocas palabras, el mecanismo de búfer triple agrega un búfer de búfer gráfico al mecanismo de búfer doble, lo que puede maximizar el uso del tiempo de inactividad. La desventaja es que se utiliza la memoria ocupada por un búfer gráfico más.

Como puede ver en la imagen, el búfer B está tardando demasiado y está utilizando A para mostrar el fotograma actual.

Pero esta vez, en lugar de perder tiempo en un búfer duplicado, el sistema crea un búfer C y comienza a procesar el siguiente fotograma. El almacenamiento en búfer triple reduce mayores exacerbaciones de jank.

El almacenamiento en búfer triple no siempre existe. Normalmente, solo se ejecuta un búfer doble, pero cuando ocurren retrasos y otras situaciones, aparece un tercer búfer para reducir el aumento de la latencia. Para obtener una introducción más detallada a las señales VSYNC y el Triple Buffering, puede consultar "Project Butter: ¿Cómo funciona y qué agregó?" 》.

El marco de renderizado de Android es muy grande y evoluciona muy rápidamente. Los amigos interesados ​​pueden leer más las referencias a continuación.