🧊 ScreenCast: la causa es EGL POR SOFTWARE en el compositor, no el portal
Con RUST_LOG=trace el log del backend tiene CINCO LÍNEAS en total y la última es la
de siempre ('Connecting' -> 'Paused'). Después no escribe nada más: ni error, ni
panic, ni progreso. O sea que el trace no aportó — screencast_thread no tiene más
instrumentación y buscar ahí estaba agotado.
La pieza que faltaba mirar era EL COMPOSITOR, que es quien entrega los frames:
15:19:02.301568Z WARN smithay::backend::egl::error: Erroneous EGL call didn't set EGLError
15:19:02.310127Z INFO …screencast_thread: state-changed 'Connecting' -> 'Paused'
↑ OCHO MILISEGUNDOS
Y la correlación no es casual: el contador de "Erroneous EGL" sube DE A DOS por cada
intento de screencast (uno al abrir el diálogo con su miniatura en vivo, otro al
pulsar Share) y no se mueve en ningún otro momento.
`ls /usr/lib/dri/` → iris_dri.so, kms_swrast_dri.so, swrast_dri.so. En QEMU con
virtio-gpu-pci sin virgl carga kms_swrast: mesa por software, SIN exportación dmabuf
real. Que es justo lo que un stream continuo necesita y una captura de una sola toma
no — por eso cosmic-screenshot SÍ funciona (va por shm) y ScreenCast no.
EL FRENTE NO ESTÁ BLOQUEADO POR UNA RECETA SINO POR EL ENTORNO. Esto reencuadra el
día entero: pipewire no era, wireplumber no era, el backend no era. Las tres piezas
están construidas, corriendo y haciendo su trabajo —el nodo `cosmic-screencast` existe
en el grafo— y el que no puede cumplir es el compositor sobre una GPU de software. Es
el MISMO muro que documenta el frente KDE (GBM/EGL de software), llegando por otro
camino.
Y no se puede verificar acá: `qemu-system-x86_64 -display help` da sólo none/gtk/sdl
y no existe virtio-gpu-gl-pci — este binario no se compiló con virgl, aunque
libvirglrenderer.so.1 esté en el host. Las salidas son metal (donde iris_dri.so YA
está en la imagen) o un QEMU con virgl.
Lo honesto: ScreenCast está verificado HASTA DONDE EL ENTORNO PERMITE — la cadena
D-Bus completa funciona, el stream se crea y se negocia, y el último tramo (los
píxeles) depende de una GPU que esta VM no tiene.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Delta semántico
Ninguna definición cambió: el cambio es de texto, documentación o datos.
2 archivos · +58 −6
diff --git a/docs/evidencia/cosmic-screencast-egl-software-2026-08-05.png b/docs/evidencia/cosmic-screencast-egl-software-2026-08-05.png
new file mode 100644
index 00000000..5af40c57
Binary files /dev/null and b/docs/evidencia/cosmic-screencast-egl-software-2026-08-05.png differ
diff --git a/docs/runbooks/cosmic-desktop.md b/docs/runbooks/cosmic-desktop.md
index 999e8e76..751a547d 100644
--- a/docs/runbooks/cosmic-desktop.md
+++ b/docs/runbooks/cosmic-desktop.md
@@ -1108,6 +1108,58 @@ El dato nuevo, que es por dónde seguir: con wireplumber corriendo, `wpctl statu
en `pw-cli ls Node` **no llega a wireplumber como stream gestionado**. El próximo movimiento es el log
del backend con `RUST_LOG=trace` alrededor de `screencast_thread`, no otra dep.
+## 🧊 LA CAUSA REAL DE ScreenCast: EGL POR SOFTWARE, no el portal (2026-08-05)
+
+Con `RUST_LOG=xdg_desktop_portal_cosmic=trace` el log del backend tiene **5 líneas en total** y la
+última es la de siempre:
+
+```
+INFO xdg_desktop_portal_cosmic::screencast_thread: state-changed 'Connecting' -> 'Paused'
+```
+
+**Después del `Paused` el backend no escribe NADA MÁS** — ni error, ni panic, ni progreso. O sea que
+el trace no aportó: `screencast_thread` no tiene más instrumentación. Buscar ahí estaba agotado.
+
+La pieza que faltaba mirar era **el compositor**, que es quien tiene que entregar los frames.
+`/tmp/cosmic-session.log`:
+
+```
+15:19:02.301568Z WARN smithay::backend::egl::error: Erroneous EGL call didn't set EGLError
+15:19:02.310127Z INFO …screencast_thread: state-changed 'Connecting' -> 'Paused'
+ ↑ 8 MILISEGUNDOS de diferencia
+```
+
+**Y la correlación no es casual**: el contador de `Erroneous EGL` sube **de a dos por cada intento de
+screencast** (uno al abrir el diálogo con su miniatura en vivo, otro al pulsar Share) y no se mueve
+en ningún otro momento. Seis acumulados tras tres intentos.
+
+`ls /usr/lib/dri/` da `iris_dri.so`, `kms_swrast_dri.so`, `swrast_dri.so`. En QEMU con
+`virtio-gpu-pci` (sin virgl) el que carga es **`kms_swrast`**: mesa por software, **sin exportación
+dmabuf real**. Y eso es exactamente lo que un stream de vídeo continuo necesita y una captura de una
+sola toma no — por eso `cosmic-screenshot` SÍ funciona (va por shm) y ScreenCast no.
+
+### El frente no está bloqueado por una receta, está bloqueado por el ENTORNO
+
+Esto reencuadra todo el día: **pipewire no era, wireplumber no era, el backend del portal no era**.
+Las tres piezas están construidas, corriendo y haciendo su trabajo —el nodo `cosmic-screencast`
+existe en el grafo—, y el que no puede cumplir es el compositor sobre una GPU de software.
+
+Es el MISMO muro que documenta el frente KDE («GBM/EGL de software; mesa es softpipe, falta llvmpipe
+o virgl»), llegando por otro camino.
+
+**No se puede verificar en este QEMU**: `qemu-system-x86_64 -display help` da sólo `none`, `gtk` y
+`sdl`, y no existe `virtio-gpu-gl-pci` — este binario no se compiló con virgl, aunque
+`libvirglrenderer.so.1` esté instalada en el host. Las dos salidas reales son:
+
+1. **Metal**, donde `iris_dri.so` (que YA está en la imagen) habla con la Intel de verdad. Es el
+ viaje de [[metal-dual-desktop-en-curso]] y probaría ScreenCast de paso.
+2. **Un QEMU con virgl** (`-device virtio-gpu-gl-pci -display egl-headless`), que hoy hay que
+ construir o instalar aparte.
+
+Hasta entonces, lo honesto es que ScreenCast está **verificado hasta donde el entorno permite**: la
+cadena completa de D-Bus funciona, el stream se crea y se negocia, y el último tramo —los píxeles—
+depende de una GPU que esta VM no tiene.
+
### Por qué es una receta propia y no la de GNOME
La de `incoming-gnome` está sellada y funciona, pero su binario NEEDea `libglib-2.0.so.0`,
@@ -1145,12 +1197,12 @@ existe, y eso cuesta igual que un bug.
## Lo que falta, en orden
-1. ~~Demonio de pipewire~~ ✅, ~~cliente persistente~~ ✅ (`portal-probe`, `b3:af49d32d`),
- ~~`wireplumber`~~ ✅ (`b3:b8f3baf0`) — **y wireplumber NO era el bloqueo**: el `Start` sigue sin
- `Response`. Lo que queda es el **backend mismo**: con `RUST_LOG=trace` alrededor de
- `screencast_thread`, mirando por qué el nodo que sí existe en `pw-cli ls Node` no aparece como
- `Video → Streams` en `wpctl`. Falta también correr `portal-probe filechooser`, que ya puede
- capturar la URI.
+1. **ScreenCast: DIAGNOSTICADO Y CERRADO como frente de software.** pipewire ✅, cliente persistente
+ ✅ (`portal-probe`, `b3:af49d32d`), `wireplumber` ✅ (`b3:b8f3baf0`) — y **ninguno era el
+ bloqueo**. La causa es **EGL por software en el compositor** (`kms_swrast`, sin dmabuf), medida
+ por correlación de 8 ms entre el `Erroneous EGL call` de smithay y el `Paused` del backend. No es
+ verificable en este QEMU (sin virgl): se cierra **en metal**, donde `iris_dri.so` ya está en la
+ imagen. Falta correr `portal-probe filechooser`, que ya puede capturar la URI.
2. **Decidir `gvfs`** (ver la corrección de arriba: las piezas ya están selladas, lo que falta es la
decisión sobre la segunda glib). Destrabaría los montajes remotos de cosmic-files y su applet.
3. **Enchufar la tienda a `.swm`**: servir `org.freedesktop.PackageKit` y encender la feature