Estructuras de datos clave en RenderingNG

Chris Harrelson
Chris Harrelson
Daniel Cheng
Daniel Cheng
Philip Rogers
Philip Rogers
Koji Ishi
Koji Ishi
Ian Kilpatrick
Ian Kilpatrick
Kyle Charbonneau
Kyle Charbonneau

Analicemos las estructuras de datos clave, que son entradas y salidas canalización de renderización.

Estas estructuras de datos son las siguientes:

  • Los árboles de marcos constan de nodos locales y remotos que representan qué web documentos en qué proceso de renderización y qué procesador Blink
  • El árbol de fragmentos inmutable representa la salida (y la entrada) de la de restricción de diseño.
  • Los árboles de propiedades representan las jerarquías de transformación, recorte, efecto y desplazamiento. de un documento web. Estos se usan en toda la canalización.
  • Las listas de visualización y los fragmentos de pintura son las entradas a los algoritmos de trama y de creación de capas.
  • Los marcos del compositor encapsulan las superficies, las superficies de renderización y la textura de la GPU. mosaicos que se usan para dibujar con la GPU.

Antes de analizar estas estructuras de datos, el siguiente ejemplo se basa en una de la revisión de arquitectura. Esta en este documento con demostraciones de cómo se pueden las estructuras de datos que se le aplican.

<!-- Example code -->
<html>
  <div style="overflow: hidden; width: 100px; height: 100px;">
    <iframe style="filter: blur(3px);
      transform: rotateZ(1deg);
      width: 100px; height: 300px"
      id="one" src="foo.com/etc"></iframe>
  </div>
  <iframe style="top:200px;
    transform: scale(1.1) translateX(200px)"
    id="two" src="bar.com"></iframe>
</html>

Enmarcar árboles

En ocasiones, Chrome puede elegir renderizar un fotograma de origen cruzado en un proceso de renderización diferente al de su marco superior.

En el código de ejemplo, hay tres marcos en total:

Un marco superior foo.com que contiene dos iframes.

Con el aislamiento de sitios, Chromium usa dos procesos de renderización para procesar esta página web. Cada proceso de renderización tiene su propia representación del árbol de marcos de esa página web:

Dos árboles de marcos que representan los dos procesos de renderización.

Una trama renderizada en un proceso diferente se representa como una trama remota. Un fotograma remoto contiene la información mínima necesaria para actuar como marcador de posición en la renderización. como sus dimensiones, por ejemplo. De lo contrario, la trama remota no contendrá ninguna información necesaria para representar su contenido real.

Por el contrario, un marco local representa un fotograma que pasa por el de procesamiento de datos. La trama local contiene toda la información necesaria para los datos para ese marco (como los datos del árbol del DOM y del estilo) en algo que se pueden renderizar y mostrar.

La canalización de renderización opera con el nivel de detalle de una fragmento del árbol de marcos local. Considera un ejemplo más complicado con foo.com como marco principal:

<iframe src="bar.com"></iframe>

Y el siguiente submarco bar.com:

<iframe src="foo.com/etc"></iframe>

Aunque todavía solo hay dos procesadores, ahora hay tres fotogramas locales fragmentos de árbol, con dos en el proceso de renderización de foo.com y uno en el proceso de renderización de bar.com:

Representación de las dos renderizaciones y los tres fragmentos del árbol de fotogramas

Para producir un marco del compositor para la página web, Viz solicita simultáneamente un marco del compositor desde el marco raíz de cada uno de los tres árboles marco locales y, luego, los agrega. Consulta también la sección de marcos del compositor.

El marco principal foo.com y el submarco foo.com/other-page son parte del mismo árbol de marcos y se renderizan en el mismo proceso. Sin embargo, los dos fotogramas aún tienen períodos ciclos de vida de documentos ya que son parte de diferentes fragmentos de árboles de marcos locales. Por este motivo, es imposible generar un marco del compositor para ambos en una sola actualización. El proceso de renderización no tiene suficiente información para componer el marco del compositor generado para foo.com/other-page directamente en el marco del compositor del marco principal de foo.com. Por ejemplo, el marco superior de bar.com fuera del proceso puede afectar la visualización del iframe de foo.com/other-url. transformando el iframe con CSS u ocultando partes de iframe con otros elementos en su DOM.

Cascada de actualización de la propiedad visual

Las propiedades visuales, como el factor de escala del dispositivo y el tamaño del viewport, afectan el resultado renderizado. y debe sincronizarse entre los fragmentos del árbol de marcos local. La raíz de cada fragmento del árbol de marcos local tiene un objeto de widget asociado. Las actualizaciones de propiedades visuales van al widget del marco principal antes de propagarse a los widgets restantes de arriba abajo.

Por ejemplo, cuando cambia el tamaño del viewport:

Diagrama del proceso que se explica en el texto anterior.

Este proceso no es instantáneo, por lo que las propiedades visuales replicadas también incluyen un token de sincronización. El compositor de Viz utiliza este token de sincronización para esperar todos los fragmentos del árbol de fotogramas local para enviar una trama del compositor con el token de sincronización actual. Con este proceso, se evita mezclar marcos del compositor con diferentes propiedades visuales.

El árbol de fragmentos inmutable

El árbol de fragmentos inmutable es el resultado de la etapa de diseño de la renderización en una canalización de integración continua. Representa la posición y el tamaño de todos los elementos de la página (sin transformaciones aplicadas).

Representación de los fragmentos en cada árbol; uno de ellos se marca como que necesita diseño.

Cada fragmento representa una parte de un elemento del DOM. Por lo general, solo hay un fragmento por elemento, pero puede haber más si se divide en diferentes páginas al imprimir o columnas en el contexto de varias columnas.

Después del diseño, cada fragmento se vuelve inmutable y nunca se vuelve a cambiar. Es importante destacar que también imponemos algunas restricciones adicionales. No:

  • Permitir cualquier "arriba" referencias en el árbol. (Un elemento secundario no puede tener un puntero hacia su elemento superior).
  • “burbuja” datos en el árbol (un elemento secundario solo lee la información de sus elementos secundarios, no de los superiores).

Esas restricciones nos permiten reutilizar un fragmento para un diseño posterior. Sin estas restricciones, a menudo tendríamos que volver a generar todo el árbol, lo cual es costoso.

La mayoría de los diseños suelen ser actualizaciones incrementales; por ejemplo, una aplicación web actualiza una pequeña parte de la IU cuando el usuario hace clic en un elemento. Idealmente, el diseño solo debería funcionar de manera proporcional a lo que en realidad cambió en pantalla. Para lograrlo, podemos reutilizar tantas partes del árbol anterior como sea posible. Esto significa que, por lo general, solo necesitamos reconstruir la columna vertebral del árbol.

En el futuro, este diseño inmutable nos permitirá hacer cosas interesantes como pasar el árbol de fragmentos inmutable a través de los límites de subprocesos si es necesario (para realizar fases posteriores en un subproceso diferente) generar varios árboles para una animación de diseño fluida, o realizar diseños especulativos paralelos. Además, nos brinda el potencial del diseño multisubproceso en sí.

Elementos de fragmentos intercalados

El contenido intercalado (texto con estilo predominantemente) usa una representación ligeramente diferente. En lugar de una estructura de árbol con cuadros y punteros representamos el contenido intercalado en una lista plana que representa el árbol. El principal beneficio es que una representación de lista plana para filas es rápida, útiles para inspeccionar o consultar estructuras de datos intercaladas, y memoria. Esto es muy importante para el rendimiento de la renderización web ya que la renderización de texto es muy compleja, y pueden convertirse con facilidad en la parte más lenta de la canalización, a menos que estén altamente optimizadas.

Se crea una lista plana para cada contexto de formato intercalado en el orden de una búsqueda en profundidad que prioriza el subárbol de diseño intercalado. Cada entrada de la lista es una tupla de (objeto, número de elementos subordinados). Por ejemplo, considera este DOM:

<div style="width: 0;">
  <span style="color: blue; position: relative;">Hi</span> <b>there</b>.
</div>

La propiedad width se establece en 0 para que la línea se ajuste entre "Hi". y "allí".

Cuando el contexto de formato intercalado para esta situación se representa como un árbol, se verá de la siguiente manera:

{
  "Line box": {
    "Box <span>": {
      "Text": "Hi"
    }
  },
  "Line box": {
    "Box <b>": {
      "Text": "There"
    }
  },
  {
    "Text": "."
  }
}

La lista plana tiene el siguiente aspecto:

  • (Cuadro de línea, 2)
  • (Casilla <span>, 1)
  • (Texto “Hola”, 0)
  • (Cuadro de línea, 3)
  • (Casilla <b>, 1)
  • (Texto "allí", 0)
  • (Texto ".", 0)

Hay muchos consumidores de esta estructura de datos: APIs de accesibilidad, y las APIs de geometría, como getClientRects: y contenteditable. Cada uno tiene diferentes requisitos. Estos componentes acceden a la estructura plana de datos a través de un cursor de conveniencia.

El cursor tiene APIs, como MoveToNext, MoveToNextLine y CursorForChildren. Esta representación de cursor es muy poderosa para el contenido de texto por varias razones:

  • Iterar en el orden de búsqueda que prioriza la profundidad es muy rápido. Se usa con mucha frecuencia porque es similar a los movimientos de acento circunflejo. Como es una lista plana, la búsqueda que prioriza la profundidad solo aumenta el desplazamiento del array, proporciona iteraciones rápidas y la localidad de la memoria.
  • Proporciona una búsqueda más amplia, lo que es necesario cuando, por ejemplo, pintar el fondo de líneas y cuadros intercalados.
  • Conocer la cantidad de elementos subordinados permite pasar al siguiente elemento del mismo nivel con rapidez. (solo aumenta el desplazamiento del array en ese número).

Árboles de propiedades

El DOM es un árbol de elementos (más nodos de texto), y CSS puede aplicar diversos estilos a los elementos.

Esto aparece de cuatro maneras:

  • Diseño: Entradas al algoritmo de restricción de diseño.
  • Paint: cómo pintar y generar tramas en el elemento (pero no sus elementos subordinados).
  • Elementos visuales: Efectos de trama o dibujos aplicados al subárbol del DOM como transformaciones, filtros y recortes.
  • Desplazamiento: esquinas redondeadas y alineadas con eje recorte y desplazamiento del subárbol contenido.

Los árboles de propiedades son estructuras de datos que explican cómo se aplican los efectos visuales y de desplazamiento a los elementos del DOM. Proporcionan los medios para responder preguntas como: dónde, en relación con la pantalla, es un elemento del DOM determinado, según el tamaño y la posición del diseño? ¿Qué secuencia de operaciones de la GPU se debería usar para aplicar efectos visuales y de desplazamiento?

Los efectos visuales y de desplazamiento en la Web son muy complicados en todo su esplendor. Lo más importante que hacen los árboles de propiedades en una única estructura de datos que represente con precisión su estructura y significado y, al mismo tiempo, elimina el resto de la complejidad del DOM y la CSS. Esto nos permite implementar algoritmos de composición y desplazamiento con mucha más confianza. En particular:

  • Geometría potencialmente propensa a errores y otros cálculos se puede centralizar en un solo lugar.
  • La complejidad de construir y actualizar árboles de propiedades se aísla en una etapa de canalización de renderización.
  • Es mucho más fácil y rápido enviar árboles de propiedades a diferentes subprocesos y procesos que el estado completo del DOM, lo que posibilita su uso para muchos casos de uso.
  • Cuantos más casos de uso haya, más beneficios obtendremos del almacenamiento en caché de geometría ya que pueden reutilizar los datos cachés.

RenderingNG usa árboles de propiedades para muchos propósitos, incluidos los siguientes:

  • Separa la composición de la pintura, y la composición del subproceso principal.
  • Determinar una estrategia óptima de composición o dibujo
  • Medir IntersectionObserver geometría.
  • Se evita el trabajo con elementos fuera de pantalla y mosaicos de texturas de GPU.
  • Invalidación de pintura y trama de forma eficiente y precisa
  • Medir Layout Shift y el procesamiento de imagen con contenido más grande en las Métricas web esenciales.

Cada documento web tiene cuatro árboles de propiedades separados: transformar, recortar, efecto y desplazar.(*) El árbol de transformación representa las transformaciones CSS y el desplazamiento. (Una transformación de desplazamiento se representa como una matriz de transformación 2D). El árbol de recortes representa clips de desbordamiento. El árbol de efectos representa todos los demás efectos visuales: opacidad, filtros, máscaras, modos de combinación y otros tipos de clips, como clip-path. El árbol de desplazamiento representa información sobre el desplazamiento, por ejemplo, cómo se desplazan encadenar juntos; necesario para realizar el desplazamiento en el subproceso del compositor. Cada nodo de un árbol de propiedades representa un desplazamiento o un efecto visual aplicado por un elemento del DOM. Si tiene varios efectos, puede haber más de un nodo del árbol de propiedades en cada árbol para el mismo elemento.

La topología de cada árbol es como una representación dispersa del DOM. Por ejemplo, si hay tres elementos del DOM con clips de desbordamiento, habrá tres nodos del árbol de clips, y la estructura del árbol de clips seguirá la relación de bloque contenedor entre los clips de desbordamiento. También hay eslabones entre los árboles. Estos vínculos indican la jerarquía relativa del DOM y, por lo tanto, el orden de aplicación de los nodos. Por ejemplo, si una transformación en un elemento del DOM se encuentra debajo de otro elemento del DOM con un filtro, entonces, por supuesto, la transformación se aplica antes que el filtro.

Cada elemento del DOM tiene un estado de árbol de propiedades. que es una tupla de 4 (transformar, recortar, efecto, desplazar) que indique el clip principal más cercano, transformar y aplicar nodos de árbol que se aplican a ese elemento. Esto es muy práctico, ya que con esta información sabemos exactamente la lista de clips, las transformaciones y los efectos que se aplican a ese elemento, y en qué orden. Esto nos indica dónde está en la pantalla y cómo dibujarlo.

Ejemplo

(fuente).

<html>
  <div style="overflow: scroll; width: 100px; height: 100px;">
    <iframe style="filter: blur(3px);
      transform: rotateZ(1deg);
      width: 100px; height: 300px"
  id="one" srcdoc="iframe one"></iframe>
  </div>
  <iframe style="top:200px;
      transform: scale(1.1) translateX(200px)" id=two
      srcdoc="iframe two"></iframe>
</html>

Para el ejemplo anterior (que es un poco diferente al de la introducción), Estos son los elementos clave de los árboles de propiedades generados:

Ejemplo de los diversos elementos en el árbol de propiedades.

Muestra listas y fragmentos de pintura

Un elemento de visualización contiene comandos de dibujo de bajo nivel (consulta aquí). que se pueden rasterizar con Skia. Los elementos de visualización suelen ser simples, con solo algunos comandos de dibujo, como dibujar un borde o un fondo. El recorrido del árbol de pintura itera sobre el árbol de diseño y los fragmentos asociados según el orden de pintura de CSS. para producir una lista de elementos de visualización.

Por ejemplo:

Un cuadro azul con las palabras &quot;Hello World&quot; dentro de un rectángulo verde.

<div id="green" style="background:green; width:80px;">
    Hello world
</div>
<div id="blue" style="width:100px;
  height:100px; background:blue;
  position:absolute;
  top:0; left:0; z-index:-1;">
</div>

Este HTML y CSS generaría la siguiente lista de visualización: donde cada celda es un elemento de visualización:

Fondo de la vista #blue en segundo plano #green en segundo plano Texto intercalado de #green
drawRect con un tamaño de 800 x 600 y color blanco. drawRect con un tamaño de 100 x 100 en la posición 0.0 y de color azul. drawRect con un tamaño de 80 x 18 en la posición 8 y 8 y de color verde. drawTextBlob con la posición 8,8 y el texto "Hello World".

La lista de elementos de visualización está ordenada de atrás hacia adelante. En el ejemplo anterior, el div verde está antes que el div azul en orden DOM. pero el orden de pintura de CSS requiere que el div azul del índice z negativo antes de (paso 3) la línea div verde. (paso 4.1). Los elementos de visualización corresponden, en términos generales, a los pasos atómicos de la especificación del orden de pintura de CSS. Un solo elemento del DOM puede generar varios elementos de visualización, Por ejemplo, #green tiene un elemento de visualización para el fondo y otro para el texto intercalado. Este nivel de detalle es importante para representar la complejidad total de la especificación del pedido de pintura de CSS como la intercalación creada por un margen negativo:

Un rectángulo verde con un cuadro gris parcialmente superpuesto y las palabras “Hello World”.

<div id="green" style="background:green; width:80px;">
    Hello world
</div>
<div id="gray" style="width:35px; height:20px;
  background:gray;margin-top:-10px;"></div>

Esto genera la siguiente lista de visualización, en la que cada celda es un elemento de visualización:

Fondo de la vista #green en segundo plano #gray en segundo plano Texto intercalado de #green
drawRect con un tamaño de 800 x 600 y color blanco. drawRect con un tamaño de 80 x 18 en la posición 8 y 8 y de color verde. drawRect con un tamaño de 35 x 20 en la posición 8 y 16,y de color gris. drawTextBlob con la posición 8,8 y el texto "Hello World".

La lista de artículos que se muestra se almacena y se vuelve a usar en actualizaciones posteriores. Si un objeto de diseño no cambió durante el recorrido del árbol de pintura, sus elementos visibles se copian de la lista anterior. Una optimización adicional se basa en una propiedad de la especificación del orden de pintura de CSS: y apilar contextos pinta de forma atómica. Si ningún objeto de diseño ha cambiado en un contexto de apilado, el recorrido del árbol de pintura omite el contexto de apilado y copia toda la secuencia de elementos de visualización de la lista anterior.

El estado actual del árbol de la propiedad se mantiene durante el recorrido del árbol de pintura y la lista de elementos de visualización se agrupa en "fragmentos" de elementos de visualización que comparten el mismo estado de árbol de propiedad. Esto se demuestra en el siguiente ejemplo:

Una caja rosa con una caja naranja inclinada.

<div id="scroll" style="background:pink; width:100px;
   height:100px; overflow:scroll;
   position:absolute; top:0; left:0;">
    Hello world
    <div id="orange" style="width:75px; height:200px;
      background:orange; transform:rotateZ(25deg);">
        I'm falling
    </div>
</div>

Esto genera la siguiente lista de visualización, en la que cada celda es un elemento de visualización:

Fondo de la vista #scroll en segundo plano Texto intercalado de #scroll #orange en segundo plano Texto intercalado de #orange
drawRect con un tamaño de 800 x 600 y color blanco. drawRect con un tamaño de 100 x 100 en la posición 0,0 y color rosa. drawTextBlob con la posición 0,0 y el texto "Hello World". drawRect con un tamaño de 75 x 200 en la posición 0.0 y de color naranja. drawTextBlob con la posición 0,0 y el texto "Estoy cayendo".

Entonces, el árbol de propiedades de la transformación y los fragmentos de pintura serían (simplificado para mayor brevedad):

Una imagen de la tabla anterior, las dos primeras celdas del bloque 1, la tercera en el bloque 2 y las últimas dos celdas del bloque 3.

La lista ordenada de bloques de pintura, que son grupos de elementos de visualización y un estado de árbol de propiedades son las entradas del paso de creación de capas de la canalización de renderización. La lista completa de bloques de pintura podría fusionarse en una sola capa compuesta y rasterizarse entre sí, pero esto requeriría una costosa rasterización cada vez que el usuario se desplazara. Podría crearse una capa compuesta para cada bloque de pintura y se rasterizarían de forma individual para evitar que se volviera a rasterizar, pero eso agotaría rápidamente la memoria de la GPU. El paso de creación de capas debe compensar la memoria de la GPU y reducir los costos cuando la situación cambia. Un buen enfoque general consiste en combinar los fragmentos de forma predeterminada, y no fusiones los trozos de pintura con estados de árboles de propiedades que se espera que cambien en el subproceso del compositor. como el desplazamiento del compositor-subproceso o las animaciones de la transformación del compositor-subproceso.

Lo ideal sería que el ejemplo anterior produzca dos capas compuestas:

  • Capa compuesta de 800 x 600 que contiene los comandos de dibujo:
    1. drawRect con un tamaño de 800 x 600 y color blanco
    2. drawRect con un tamaño de 100 x 100 en la posición 0,0 y color rosa
  • Capa compuesta de 144 x 224 que contiene los comandos de dibujo:
    1. drawTextBlob con la posición 0,0 y el texto "Hello World"
    2. traducir 0,18
    3. rotateZ(25deg)
    4. drawRect con un tamaño de 75 x 200 en la posición 0 y color naranja
    5. drawTextBlob con la posición 0,0 y el texto "Me estoy cayendo"

Si el usuario se desplaza por #scroll, se mueve la segunda capa compuesta, pero no se necesita la rasterización.

Por ejemplo, de la sección anterior sobre árboles de propiedades, hay seis trozos de pintura. Junto con los estados del árbol de propiedades (transformar, recortar, efecto, desplazarse) son los siguientes:

  • Fondo del documento: Desplazamiento del documento, clip del documento, raíz, desplazamiento del documento.
  • Esquina horizontal, vertical y esquina de desplazamiento para div (tres bloques de pintura separados): Desplazamiento de documento, clip de documento, desenfoque #one, desplazamiento del documento.
  • Iframe #one: rotación de #one, clip de desplazamiento de desbordamiento, #one desenfoque, desplazamiento de div.
  • Iframe #two: escala #two, clip de documento, raíz, desplazamiento de documentos.

Marcos del compositor: superficies, superficies de renderización y mosaicos de texturas de GPU

El navegador y los procesos de renderización administran la rasterización del contenido. luego envía los marcos del compositor al proceso de Viz para su presentación en pantalla. Los fotogramas del compositor representan cómo unir contenido de trama y dibujarlos eficientemente con la GPU.

Tarjetas

En teoría, un proceso de renderización o un compositor de procesos del navegador podrían rasterizar píxeles en una sola textura, el tamaño completo del viewport del renderizador y envía esa textura a Viz. Para mostrarla, el compositor de pantalla solo tendría que copiar los píxeles de esa textura única a la posición correcta en el búfer de fotogramas (por ejemplo, la pantalla). Sin embargo, si ese compositor quisiera actualizar incluso un solo píxel, tendría que volver a rasterizar la viewport completa y enviar una nueva textura a Viz.

En cambio, el viewport se divide en mosaicos. Un mosaico de textura de GPU separado respalda cada mosaico con los píxeles rasterizados que forman parte del viewport. El renderizador puede actualizar mosaicos individuales o incluso solo cambia la posición en pantalla de los mosaicos existentes. Por ejemplo, cuando te desplazas por un sitio web, la posición de los mosaicos existentes cambiaba hacia arriba y solo ocasionalmente se deberá rasterizar un nuevo mosaico para el contenido que se encuentra más abajo en la página.

Cuatro tarjetas.
En esta imagen, se muestra un día soleado con cuatro mosaicos. Cuando se produce un desplazamiento, comienza a aparecer un quinto mosaico. Uno de los mosaicos tiene un solo color (celeste), y hay un video y un iframe en la parte superior.

Cuatriciclos y superficies

Los mosaicos de texturas de GPU son un tipo especial de cuadro, que es solo un nombre elegante para una categoría de textura u otra. Un cuadrante identifica la textura de entrada e indica cómo transformarla y aplicarle efectos visuales. Por ejemplo, las tarjetas de contenido normales tienen una transformación que indica su posición x e y en la cuadrícula de mosaicos.

Mosaicos de texturas de GPU.

Estos mosaicos rasterizados se unen en un pase de renderización, que es una lista de cuádruplos. El pase de renderización no contiene información de píxeles. en su lugar, tiene instrucciones sobre dónde y cómo dibujar cada cuadrante para producir el resultado deseado de píxeles. Hay un cuadro de dibujo para cada tarjeta de textura de la GPU. El compositor de anuncios gráficos tiene que iterar a través de la lista de cuádruplos dibujar cada uno con los efectos visuales especificados, a fin de producir la salida de píxeles deseada para el pase de renderización. La composición de cuádruplos de dibujo para un pase de renderización se puede realizar de manera eficiente en la GPU. porque se eligen cuidadosamente los efectos visuales permitidos para que se asignen directamente a funciones de GPU.

Existen otros tipos de cuádruplos de dibujo más allá de las tarjetas en trama. Por ejemplo, hay cuadros de dibujo de color sólido que no están respaldados por una textura, o cuadros de diseño de texturas para texturas que no son de mosaicos, como un video o un lienzo.

También es posible que un marco del compositor incorpore otro marco del compositor. Por ejemplo, el compositor del navegador produce un marco del compositor con la IU del navegador. y un rectángulo vacío en el que se incorporará el contenido del compositor de renderización. Otro ejemplo son los iframes aislados del sitio. Esta incorporación se realiza a través de plataformas.

Cuando un compositor envía un marco del compositor, va acompañado de un identificador, denominada ID de plataforma, lo que permite que otros marcos del compositor lo incorporen por referencia. Viz almacena el fotograma más reciente del compositor enviado con un ID de superficie particular. Luego, otro marco del compositor puede hacer referencia a él más tarde a través de un cuadro de dibujo de superficie. y, por lo tanto, Viz sabe qué dibujar. (Ten en cuenta que los cuadrantes de dibujo de superficie solo contienen ID de superficie, no texturas).

Pases de renderización intermedios

Algunos efectos visuales, como muchos filtros o modos de combinación avanzados, requieren que dos o más cuádruplos se dibujen para obtener una textura intermedia. Luego, la textura intermedia se dibuja en un búfer de destino en la GPU (o posiblemente otra textura intermedia). aplicar el efecto visual al mismo tiempo. Para permitir esto, un marco del compositor contiene una lista de pases de renderización. Siempre hay un pase de renderización raíz, que se dibuja último y cuyo destino corresponde al búfer de fotogramas, y puede haber más.

La posibilidad de múltiples pases de renderización explica el nombre. "render pass". Cada pase debe ejecutarse de manera secuencial en la GPU, en múltiples “pases”, mientras que un solo pase puede completarse en un solo cálculo de GPU masivamente paralelo.

Agregación

Se envían múltiples marcos del compositor a Viz, y deben dibujarse juntos en la pantalla. Esto se logra mediante una fase de agregación que los convierte en marco agregado del compositor. La agregación reemplaza los cuadrantes de dibujo de superficie por los marcos del compositor que especifiquen. También es una oportunidad para optimizar las texturas intermedias innecesarias o el contenido que está fuera de la pantalla. Por ejemplo, en muchos casos, el marco del compositor para un iframe aislado del sitio no necesita su propia textura intermedia, y se puede dibujar directamente en el búfer de fotogramas con los cuadros de dibujo adecuados. La fase de agregación descifra tales optimizaciones y las aplica en función del conocimiento global al que no pueden acceder los compositores de renderización individuales.

Ejemplo

Estos son los marcos del compositor que representan el ejemplo del principio del esta publicación.

  • Plataforma de foo.com/index.html: id=0
    • Pase de renderización 0: Dibuja para el resultado.
      • Pase de renderización para dibujar cuadrantes: dibuja con un desenfoque de 3 px y recorta en el pase de renderización 0.
        • Pase de renderización 1:
          • Dibuja cuádruplos para el contenido de tarjetas del iframe de #one, con posiciones "x" e "y" para cada uno.
      • Cuadrante de dibujo de superficie: con ID 2, dibujado con la transformación de escala y traducción.
  • Plataforma de la IU del navegador: ID=1
    • Pase de renderización 0: Dibuja para el resultado.
      • Dibuja cuadrantes para la IU del navegador (también se muestran en mosaico)
  • Plataforma de bar.com/index.html: ID=2
    • Pase de renderización 0: Dibuja para el resultado.
      • Dibuja cuádruplos para el contenido del iframe #two, con las posiciones "x" e "y" para cada uno.

Ilustraciones de Una Kravets.