atuq: no era el perfil — son DOS SALIDAS, y el «3 de 13» medía la cámara
Dos cosas antes de la medición: el MOZ_LOG de las que pintan y las que no termina IDÉNTICO (las dos
commitean WaylandBufferSHM de 1280x696), y el cruce de las 15 corridas está confundido — las 13 de
«perfil del usuario» salieron todas con VGA=1.
`screendump` de QMP fotografía UN dispositivo. Con VGA=1 hay dos, y hasta ahora se miraba uno. Con
`id=` en cada uno y capturando los dos en cada toma, en la misma corrida y el mismo instante:
+312s ██ PRIMERA PINTURA — 704456 px EN vga0
gpu0 = 962675 px de fondo + panel y dock (el escritorio, SIN navegador)
vga0 = 703766 px magenta (la ventana, con la página)
⇒ cosmic-comp maneja las DOS salidas y la ventana cae en una u otra. «Pinta 3 de 13» era cuántas
veces cayó en la pantalla que yo fotografiaba: una tasa de mi cámara, no del producto. El §6.10.ter
tiene la misma explicación (aquel arranque también traía `drm: card0 card1`).
Queda en pie, ya sin confundido: el navegador arranca, mapea y commitea SIEMPRE; cuando la ventana
está en la pantalla que se mira, se ve entre +184 y +312 s; el perfil no era la causa y cosmic-comp
nesteado tampoco.
⚠ Tercera vez en el día con la misma forma: un ✗ de una captura de UNA pantalla no dice «la ventana
no está», dice «no está en ESA» — igual que `mapped 1` no probaba que se viera. El estado anota ahora
en qué pantalla apareció y cuántas se fotografiaron, y el vigía NO cuenta las ciegas: las nombra.
This commit is contained in:
@@ -46,7 +46,13 @@ SMP = os.environ.get("SMP", "2")
|
||||
# Un compositor con dos tarjetas puede componer en la que el `screendump` NO muestra. Por eso el
|
||||
# default acá es UNA sola (-vga none) y la reproducción del caso original es una opción explícita:
|
||||
# son dos mediciones distintas y hay que poder pedir cada una por su nombre.
|
||||
VGA_ARGS = [] if os.environ.get("VGA") == "1" else ["-vga", "none"]
|
||||
# Las dos pantallas van con ID EXPLÍCITO (`vga0`, `gpu0`) y no por el `-vga std` implícito, porque
|
||||
# `screendump` de QMP fotografía UN dispositivo y hay que poder pedir cada uno por su nombre: con dos
|
||||
# salidas, el compositor puede poner la ventana en la que la captura por defecto NO muestra, y eso se
|
||||
# ve exactamente igual que «la ventana no aparece».
|
||||
DOS_PANTALLAS = os.environ.get("VGA") == "1"
|
||||
VGA_ARGS = (["-vga", "none", "-device", "VGA,id=vga0"] if DOS_PANTALLAS else ["-vga", "none"])
|
||||
PANTALLAS = ["gpu0", "vga0"] if DOS_PANTALLAS else ["gpu0"]
|
||||
|
||||
|
||||
class Serial:
|
||||
@@ -115,6 +121,18 @@ class Serial:
|
||||
return self.esperar(marca, segundos, nombre=f"de «{orden[:40]}»")
|
||||
|
||||
|
||||
def capturar(ruta_qmp, out, nombre):
|
||||
"""Fotografía CADA pantalla del guest y devuelve {pantalla: fichero}.
|
||||
|
||||
Con dos salidas hay que mirar las dos: la ventana puede estar viva y dibujando en la que no se
|
||||
fotografía, y eso es indistinguible de «no pinta» si sólo se mira una.
|
||||
"""
|
||||
ficheros = {p: os.path.join(out, f"{nombre}-{p}.ppm") for p in PANTALLAS}
|
||||
qmp(ruta_qmp, [{"execute": "screendump", "arguments": {"filename": f, "device": p}}
|
||||
for p, f in ficheros.items()])
|
||||
return ficheros
|
||||
|
||||
|
||||
def pintado(ppm):
|
||||
"""¿Cuántos píxeles de la pantalla son la página de prueba?
|
||||
|
||||
@@ -132,7 +150,7 @@ def pintado(ppm):
|
||||
return sum(n for n, (r, g, b) in im.getcolors(1 << 24) if r > 90 and b > 90 and g < 40)
|
||||
|
||||
|
||||
def anotar_medicion(segundos, a):
|
||||
def anotar_medicion(segundos, a, pantalla=None):
|
||||
"""Deja el tiempo de primera pintura en `docs/state/primera-pintura.json`.
|
||||
|
||||
Va al estado del repo y no a un log porque quien pregunta «¿esta imagen se puede usar?» es
|
||||
@@ -145,11 +163,14 @@ def anotar_medicion(segundos, a):
|
||||
"medido": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()),
|
||||
"imagen": IMG,
|
||||
"segundos_primera_pintura": segundos, # None = no pintó dentro de la ventana
|
||||
"pantalla": pantalla, # EN CUÁL de las salidas apareció (medido 2026-09-14:
|
||||
# con dos, la ventana cae en cualquiera de las dos)
|
||||
"pantallas_fotografiadas": len(PANTALLAS), # con 1 y dos salidas, un ✗ NO es concluyente
|
||||
"presupuesto_s": a.budget,
|
||||
"ventana_s": a.wait,
|
||||
"cadencia_s": a.cadence, # la RESOLUCIÓN del número: ±cadencia
|
||||
"lanzamiento": "perfil del usuario" if a.as_user else "perfil nuevo en tmpfs",
|
||||
"video": "vga+virtio-gpu (dos DRM)" if VGA_ARGS == [] else "virtio-gpu solo (-vga none)",
|
||||
"video": "vga+virtio-gpu (dos DRM)" if DOS_PANTALLAS else "virtio-gpu solo (-vga none)",
|
||||
"mem_mb": int(MEM), "vcpus": int(SMP), "acel": "tcg",
|
||||
"guion": "scripts/cosmic/atuq-en-imagen.py",
|
||||
}
|
||||
@@ -214,7 +235,7 @@ def main():
|
||||
qemu = [
|
||||
"nice", "-n", "10", "qemu-system-x86_64",
|
||||
"-machine", "q35", "-accel", "tcg", "-cpu", "max", "-m", MEM, "-smp", SMP,
|
||||
*VGA_ARGS, "-device", "virtio-gpu-pci", "-display", "none", "-nic", "none",
|
||||
*VGA_ARGS, "-device", "virtio-gpu-pci,id=gpu0", "-display", "none", "-nic", "none",
|
||||
"-drive", f"if=pflash,format=raw,unit=0,file={OVMF_CODE},readonly=on",
|
||||
"-drive", f"if=pflash,format=raw,unit=1,file={vars_fd}",
|
||||
"-drive", f"file={IMG},format=raw,if=virtio",
|
||||
@@ -244,8 +265,8 @@ def main():
|
||||
print(ser.cmd("echo ENTORNO: WD=$WAYLAND_DISPLAY XDG=$XDG_RUNTIME_DIR DBUS=$DBUS_SESSION_BUS_ADDRESS").strip())
|
||||
print(ser.cmd("ls -l $XDG_RUNTIME_DIR; ls /usr/lib/dri").strip())
|
||||
|
||||
qmp(qmp_sock, [{"execute": "screendump", "arguments": {"filename": os.path.join(out, "antes.ppm")}}])
|
||||
print("== captura ANTES", flush=True)
|
||||
capturar(qmp_sock, out, "antes")
|
||||
print("== captura ANTES (%s)" % ", ".join(PANTALLAS), flush=True)
|
||||
|
||||
if a.only_cosmic:
|
||||
print("== CONTROL: no se lanza el navegador")
|
||||
@@ -278,21 +299,23 @@ def main():
|
||||
primera = None # segundos hasta la PRIMERA captura con la página en pantalla
|
||||
while time.time() - t0 < a.wait:
|
||||
time.sleep(a.cadence); n += 1
|
||||
shot = os.path.join(out, f"durante-{n}.ppm")
|
||||
qmp(qmp_sock, [{"execute": "screendump", "arguments": {"filename": shot}}])
|
||||
tomas = capturar(qmp_sock, out, f"durante-{n}")
|
||||
t = int(time.time() - t0)
|
||||
px = pintado(shot)
|
||||
medidas = {p: pintado(f) for p, f in tomas.items()}
|
||||
px = max((v for v in medidas.values() if v is not None), default=None)
|
||||
donde = next((p for p, v in medidas.items() if v and v > 100_000), None)
|
||||
if primera is None and px and px > 100_000:
|
||||
primera = t
|
||||
print(f" +{t}s ██ PRIMERA PINTURA — {px} px de la página", flush=True)
|
||||
print(f" +{t}s ██ PRIMERA PINTURA — {px} px de la página EN {donde}", flush=True)
|
||||
if a.until_paint:
|
||||
break
|
||||
else:
|
||||
vivos = ser.cmd("for c in /proc/[0-9]*/comm; do cat $c 2>/dev/null; done | grep -c atuq")
|
||||
v = vivos.splitlines()[1].strip() if len(vivos.splitlines()) > 1 else "?"
|
||||
print(f" +{t}s px de la página: {px if px is not None else '?'} procesos atuq: {v}", flush=True)
|
||||
detalle = " ".join(f"{p}={medidas[p]}" for p in PANTALLAS)
|
||||
print(f" +{t}s px de la página: {detalle} procesos atuq: {v}", flush=True)
|
||||
|
||||
qmp(qmp_sock, [{"execute": "screendump", "arguments": {"filename": os.path.join(out, "despues.ppm")}}])
|
||||
capturar(qmp_sock, out, "despues")
|
||||
print("== captura DESPUES", flush=True)
|
||||
|
||||
# EL NÚMERO. No «pinta / no pinta»: CUÁNTO TARDA. Medido el 2026-09-14 sobre esta misma
|
||||
@@ -314,7 +337,7 @@ def main():
|
||||
# El número se PUBLICA donde lo pueda leer el vigía de la imagen, que es estático y no
|
||||
# arranca nada: sin esto el dato vive en el scrollback del que corrió la VM y se pierde,
|
||||
# que es exactamente lo que pasó con la corrida a mano del §6.10.ter.
|
||||
anotar_medicion(primera, a)
|
||||
anotar_medicion(primera, a, donde if primera is not None else None)
|
||||
|
||||
# La evidencia que no se puede leer de una captura: qué hizo el widget de Wayland.
|
||||
print("---- atuq.log (cola) ----")
|
||||
|
||||
Reference in New Issue
Block a user