← bitácora

Stage 1: píxeles en pantalla

Lo primero que hizo rumb fue meter una página web dentro de una ventana de GPUI, y lo hizo de la forma más burda que podía funcionar.

Servo se construye con un contexto de render offscreen — un contexto GPU real hecho a partir del handle de display del host, pero con una superficie que nadie compone, de modo que GPUI sigue siendo dueño del drawable que la pantalla muestra de verdad. En cada tick de render girábamos el bucle de eventos de Servo, le decíamos al WebView que pintara y luego llamábamos a read_to_image sobre ese framebuffer offscreen para traer los píxeles de vuelta a la memoria del sistema. Servo los entrega en RGBA y GPUI los quiere en BGRA, así que intercambiábamos rojo y azul a mano en todo el buffer y le pasábamos el resultado a paint_image como si fuera una imagen que alguien hubiera cargado desde disco.

Era lento exactamente como cabía esperar: un viaje de ida y vuelta completo por la CPU, una vez por frame, para unos píxeles que nunca habían salido de la tarjeta. La cadencia de frames venía únicamente de request_animation_frame y las actualizaciones en pantalla iban rezagadas en torno a 1 Hz. El redimensionado no estaba conectado. A la página no llegaba absolutamente ningún input.

Todo eso ya lo sabíamos al escribirlo. La intención no era tener un camino rápido, era averiguar si Servo se podía embeber siquiera en una aplicación GPUI — si los dos bucles de eventos podían compartir proceso, si el malabarismo de contextos aguantaba, si por el otro extremo salía una página. En cuanto salió una, la pregunta dejó de ser «¿es esto posible?» y pasó a ser «¿cómo evitamos que el frame toque la CPU?», que es un sitio mucho mejor donde quedarse atascado. El readback nunca estuvo pensado para sobrevivir al contacto con Stage 2.

GPU SYSTEM MEMORY Servo offscreen framebuffer GPUI paints read_to_image every frame copy, then R↔B swap upload as a texture a full round trip, per frame
El framebuffer de Servo hace un viaje de ida y vuelta por la memoria del sistema y un intercambio de color antes de que GPUI pueda dibujarlo.