← bitàcola

Fase 2: el fotograma no surt mai de la GPU

Una setmana després, l'anada i tornada per la CPU ha desaparegut. No pas optimitzada — desapareguda.

Servo continua pintant en el seu propi framebuffer fora de pantalla, a través d'un context de render que el nostre fork construeix a partir del handle de display de l'amfitrió, amb una superfície que ningú no compon, de manera que GPUI conserva la propietat del drawable que la pantalla mostra de debò. El que ha canviat és què passa després. Quan Servo dona un fotograma per llest, tick() demana a aquell context que exporti el framebuffer i en rep un handle: un descriptor de fitxer dma-buf per a la memòria de la GPU, i un fence que indica quan les escriptures ja s'han completat. Tots dos passen a ser propietat nostra. El handle va a parar a una casella compartida amb el costat de GPUI.

L'altra meitat viu al backend de wgpu de GPUI. draw_external_sprites recull el handle, importa el dma-buf com a wgpu::Texture a través de wgpu::hal::vulkan i d'ash, i el dibuixa com un sprite més de l'escena. Per a GPUI, la pàgina web és una textura com qualsevol altra. El camí de la fase 1 — el readback, l'intercanvi de vermell i blau, una pujada de RenderImage a cada fotograma — està esborrat, no desactivat. Ja no hi ha res que reboti per la memòria del sistema.

El fence és la part delicada. Un sync fd és d'un sol ús: quan algú ja hi ha esperat, tornar-hi a esperar no té cap significat definit. Per això el donem al primer consumidor del fotograma i deixem que la resta caiguin en una espera de gra més gruixut. El handle dma-buf sí que el mantenim a la memòria cau, i per això un fotograma en què Servo no ha pintat res encara mostra l'últim de bo en comptes de parpellejar.

El reenviament de ratolí i scroll va entrar el mateix dia. Va ser llavors quan la pàgina va respondre un clic per primera vegada. Fins aleshores era una captura de pantalla caríssima que, a més a més, s'anava actualitzant.

GPU SYSTEM MEMORY Servo offscreen framebuffer GPUI paints dma-buf fd + fence nothing crosses here any more
El handle dma-buf i el fence van directes de Servo a GPUI; el carril de memòria del sistema no porta res.