Skip to content

Add a display-check builtin and per-display screenshots - #69

Open
scottjones wants to merge 2 commits into
chriskearney:mainfrom
scottjones:display-check
Open

scottjones wants to merge 2 commits into
chriskearney:mainfrom
scottjones:display-check

Conversation

@scottjones

Copy link
Copy Markdown
Contributor

Bringing up external displays on Apple Silicon (USB-C DisplayPort through a dcpext DCP, HDMI through the dptx PHY on boards like j504) has meant a hand-written script in every lab job, and job screenshots only ever showed the built-in panel.

--test display-check records every DRM connector: its status, whether it's enabled, its modes, the mode it runs now, and its parsed EDID. The EDID's serial number is never recorded. It also records whether a dcpext is bound to its driver, and this boot's DCP crashes and DART faults. It writes display.json and summary.txt into the job's artifacts. --display-wait / --display-expect make it wait for an external connector first. It only fails on a DCP crash, a DART fault during the check, an expected connector that never connected, or a kernel log it couldn't read (so it can't count crashes or faults). The MCP lab_run tool takes the same options.

When two or more displays are active, each job screenshot now also captures every CRTC on its own, as screen/after-boot-<connector>.jpg. The existing after-boot.jpg / after-tests.jpg don't change. A per-display capture shows the compositor drew to that framebuffer and the modeset worked. It doesn't show link training, or that the monitor lit up.

Not in this PR: picking a connector for the live screenshot (it still grabs one display), and per-display capture through the grim fallback.

Test plan

  • go vet ./... and go test ./... pass
  • Unit tests with fixture data: EDID parsing and serial redaction, connector sysfs, DCP/dcpext binding, kernel-log crash and fault counting, debugfs DRM state to active outputs, the wait, pass/fail rules, CLI/API validation
  • A labd plus simulated-Mac test: two displays give per-connector screenshots, one display gives none
  • Broke the code on purpose (EDID serial redaction, DART fault counting) and watched the tests fail, then restored it
  • On a Mac with an external monitor on USB-C: lab run <mac> --test display-check --display-expect any --display-wait 10m, plug the monitor in during the wait, then check test-display-check/summary.txt and screen/after-tests-DP-*.jpg
  • The same on an HDMI board (j504)
  • Check that real /sys/kernel/debug/dri/*/state output parses as the fixtures do, and that ffmpeg kmsgrab -plane_id grabs the external plane

🤖 Generated with Claude Code

scottjones and others added 2 commits November 6, 2026 06:44
On Apple DRM the internal panel's DCP and each dcpext are separate CRTCs
of one card, and kmsgrab with no plane grabs the first active plane, so a
job's screenshots only ever showed the built-in panel.

lab-agent now reads the card's atomic state from debugfs, finds each
connector driven by an active CRTC and the bottom plane scanned out on it,
and, when two or more displays are active, captures each with kmsgrab
-plane_id as screen/<label>-<connector>.jpg. screen/after-boot.jpg and
after-tests.jpg are unchanged. The grim fallback and the live screenshot
still capture one image.

A per-display capture shows the compositor drew to that framebuffer and
the CRTC's modeset succeeded, not that the link trained or a monitor
shows a picture.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
External display bring-up on Apple Silicon (USB-C DisplayPort through a
dcpext DCP, HDMI through the dptx PHY on boards like j504) needed a
hand-written script in every job. display-check records, per DRM
connector, its status, whether it is enabled, its modes, the mode its
CRTC runs, and its EDID's manufacturer, product, monitor name, year,
physical size and preferred mode. It never records an EDID serial number,
the raw EDID, or anything that identifies the Mac. It also records each
DCP and dcpext device and whether a driver is bound, and this boot's DCP
crashes and DART faults from the kernel log. It writes display.json and
summary.txt into the job's artifacts.

--display-wait waits for an external connector to connect first;
--display-expect names the one the job expects (DP-1, HDMI-*, any). The
test is informational: it fails only on a DCP crash this boot, a DART
fault during the check, an expected connector that didn't connect in
time, or a kernel log it could not read (it can't count crashes or
faults without one). lab_run over MCP takes the same options.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant