Summary
Eliminate the CPU readback in the Servo → compositor path by sharing GPU textures via Linux DMA-BUF. Currently, every frame goes through SoftwareRenderingContext::read_to_image() which copies pixel data from the CPU-side llvmpipe buffer into a Vec<u8>, then the compositor uploads it to a wgpu texture. With DMA-BUF, Servo's GL framebuffer can be exported as a file descriptor and imported directly by wgpu as a texture — zero CPU pixel copies.
Parent issue: #167
Depends on: #323 (PoC — merged)
Blocked by: Nothing (can start independently)
Architecture
Current path (CPU readback):
Servo (llvmpipe GL) → glReadPixels → Vec<u8> → wgpu::Queue::write_texture → compositor
Proposed path (DMA-BUF zero-copy):
Servo (EGL/GL) → eglExportDMABUFImageMESA → DMA-BUF fd
→ wgpu-hal import (VkImage from fd) → compositor texture layer
Key EGL extensions
EGL_MESA_image_dma_buf_export — export an EGLImage to a DMA-BUF fd + fourcc + stride
EGL_EXT_image_dma_buf_import — import a DMA-BUF fd as an EGLImage (wgpu side)
Prerequisites
- Servo must use a hardware
RenderingContext (EGL-based, not SoftwareRenderingContext)
- The system must have a GPU with DMA-BUF support (most Mesa drivers, NVIDIA 515+)
- wgpu must be using a Vulkan backend (for
VkImportMemoryFdInfoKHR)
Implementation Steps
-
Switch Servo to EGL rendering context — replace SoftwareRenderingContext with a hardware EGL context (e.g. via surfaceless EGL or GBM platform). This requires Servo to render on a real GPU.
-
Export GL FBO as DMA-BUF — after webview.paint(), use eglExportDMABUFImageMESA to get the fd, fourcc, stride, and offset of the rendered frame.
-
Import DMA-BUF into wgpu — use wgpu-hal's unsafe Vulkan API to import the DMA-BUF fd as a VkImage via VkImportMemoryFdInfoKHR, then wrap it as a wgpu::Texture.
-
GL↔Vulkan synchronization — use EGL_KHR_fence_sync / VkSemaphore with fd export/import to ensure the GL render is complete before Vulkan reads the texture.
-
Fallback path — if DMA-BUF extensions are unavailable (e.g. in CI, headless without GPU), fall back to the existing CPU readback path.
Acceptance Criteria
Complexity
Effort: L (1–2 weeks)
Involves EGL extension plumbing, wgpu-hal unsafe API, cross-API synchronization, and proper fallback logic.
References
Notes
Summary
Eliminate the CPU readback in the Servo → compositor path by sharing GPU textures via Linux DMA-BUF. Currently, every frame goes through
SoftwareRenderingContext::read_to_image()which copies pixel data from the CPU-side llvmpipe buffer into aVec<u8>, then the compositor uploads it to a wgpu texture. With DMA-BUF, Servo's GL framebuffer can be exported as a file descriptor and imported directly by wgpu as a texture — zero CPU pixel copies.Parent issue: #167
Depends on: #323 (PoC — merged)
Blocked by: Nothing (can start independently)
Architecture
Key EGL extensions
EGL_MESA_image_dma_buf_export— export anEGLImageto a DMA-BUF fd + fourcc + strideEGL_EXT_image_dma_buf_import— import a DMA-BUF fd as anEGLImage(wgpu side)Prerequisites
RenderingContext(EGL-based, notSoftwareRenderingContext)VkImportMemoryFdInfoKHR)Implementation Steps
Switch Servo to EGL rendering context — replace
SoftwareRenderingContextwith a hardware EGL context (e.g. via surfaceless EGL or GBM platform). This requires Servo to render on a real GPU.Export GL FBO as DMA-BUF — after
webview.paint(), useeglExportDMABUFImageMESAto get the fd, fourcc, stride, and offset of the rendered frame.Import DMA-BUF into wgpu — use
wgpu-hal's unsafe Vulkan API to import the DMA-BUF fd as aVkImageviaVkImportMemoryFdInfoKHR, then wrap it as awgpu::Texture.GL↔Vulkan synchronization — use
EGL_KHR_fence_sync/VkSemaphorewith fd export/import to ensure the GL render is complete before Vulkan reads the texture.Fallback path — if DMA-BUF extensions are unavailable (e.g. in CI, headless without GPU), fall back to the existing CPU readback path.
Acceptance Criteria
wgpu::Textureviawgpu-halunsafe APIservo-gpuor similar (Linux-only)Complexity
Effort: L (1–2 weeks)
Involves EGL extension plumbing,
wgpu-halunsafe API, cross-API synchronization, and proper fallback logic.References
EGL_MESA_image_dma_buf_exportspecificationEGL_EXT_image_dma_buf_importspecificationVK_KHR_external_memory_fd— Vulkan extension for importing DMA-BUF memoryNotes
wgpu::Texturethat can be consumed by the compositor directly. If perf(plugins/servo): zero-copy Servo → compositor via DMA-BUF texture sharing #349 lands first, the imported texture could be wrapped inVideoData::Gpufor a fully zero-copy path through the entire pipeline.