Repository navigation
test(gl): fail instead of skipping when the GPU mixer breaks - #917
Conversation
560b54e to
aea811e
Compare
srperens
left a comment
There was a problem hiding this comment.
Verdict: Comment. The three changes are correct and each closes a real false-green. There are two gaps. The element checks re-implement a helper that landed on main today. And the one platform where the new expects can fire has not run this head in this repo's CI.
Requested changes
- Rebase onto
mainand route the missing-element case throughbackend/tests/common/mod.rs. Usecommon::missing_elements(&[...]), and ifSTROM_REQUIRE_GLis set, fail first. Then returncommon::require_or_skip(&missing). 34008fe (#912) added that helper so that "every skip on a missing element goes through here, so none can quietly opt out". This PR adds two more hand-rolled copies of the sameSTROM_REQUIRE_GST_PLUGINSpanic:backend/tests/shader_validation_test.rs:110—fn gl_elements_available() -> bool {andbackend/tests/vision_mixer_fx_test.rs:71—let missing: Vec<&str> = ["glvideomixerelement", "glshader", "gltestsrc"].STROM_REQUIRE_GLis the only part the helper lacks. The PR's merge base (a8ace5f) predates #912, so it could not have used it.
Needs the maintainer
- Add the
ci:macoslabel. On Linux both GL binaries stop at the no-context skip (the body says so, and I agree: theexpects sit aftergl_available_or_required()). So the build and startexpects atbackend/tests/vision_mixer_fx_test.rs:156—.expect("GPU vision mixer pipeline builds");and:423have never executed in this repo's CI. The fork run in the body is not a check on this PR.
Claims
| Claim | Verdict | Evidence |
|---|---|---|
A GPU build/start failure used to skip even under STROM_REQUIRE_GL |
CONFIRMED |
The removed arms eprintln!("SKIP: could not build GPU pipeline ({})", e); return; ran after the GL probe had already returned true. |
| Missing GL elements were folded into "no context" | CONFIRMED |
The removed find(...).is_none() ... return false sat inside gl_environment_available, and the Linux job skips on that function's false result. |
| Overlay state is process-global and keyed by block ID | CONFIRMED |
backend/src/blocks/builtin/vision_mixer/overlay.rs:27 — /// Global registry of vision mixer overlay states, keyed by block instance ID., backed by a static INSTANCE: OnceLock<...>. Two tests sharing "vmfx" in one binary could therefore collide. |
| The new failures fire on revert | UNVERIFIED |
These are the author's macOS runs only. This repo has no macOS run at aea811e. |
Diagnosis: This is the right layer. Each change turns a silent return into either a panic or an expect, and the no-context skip that headless Linux legitimately needs is kept. Coverage is BOUNDED to these two files. ElementFactory::find proves that an element is registered, not that it loads. In both files a gl_environment_available() render probe follows the element check and proves loading, so that is not a gap here.
Radius: LOCAL. The diff touches test files only.
Overlaps: #809, #806 and #803 also edit backend/tests/vision_mixer_fx_test.rs. Those are textual conflicts; none of them settles a design question here. The body already names all three.
Tests & CI: At aea811e, Check (Linux), both Linux builds, WASM and API Contract are green, and Build (macOS) and Build (Windows) show skipping. I did not fetch the Linux job log for the GL binaries' timing. The 0.04–0.05 s figure is the author's.
Confidence: HIGH
vision_mixer_fx_test printed SKIP and passed when the GPU vision mixer failed to build or start, even after the GL probe had proven the environment renders and even under STROM_REQUIRE_GL. A GPU mixer that stopped building passed green on the macOS job. Those paths now fail. Missing GL elements were folded into "no GL context", which the Linux jobs treat as a legitimate skip. Every CI job installs the GL plugins, so both GL test files now fail on a missing GL element under STROM_REQUIRE_GST_PLUGINS, like every other missing element, and also under STROM_REQUIRE_GL, since a platform that must render cannot do it without them. The two fx tests shared block ID "vmfx". The vision mixer's overlay state is process-global and keyed by block ID, and the tests run concurrently, so the letterbox test now uses its own ID. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Both GL test files hand-rolled the STROM_REQUIRE_GST_PLUGINS check that common::require_or_skip already owns. common::gl_elements_available adds the one thing that helper lacks, failing under STROM_REQUIRE_GL too, and both files now call it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
aea811e to
7d9968c
Compare
|
Claude (AI) here, replying on Peter Wagenet's account. Requested change: done in 7d9968c, after rebasing onto With the GL plugin hidden, all 4 tests fail under either variable and skip with neither set. Details are in the PR body.
The first macOS attempt failed earlier in the run, in |
srperens
left a comment
There was a problem hiding this comment.
Supersedes my review at aea811e (Comment). Re-reviewed at 7d9968c, which is a rebase onto main plus one new commit. Against main the diff is now three test files. The verdict stays at Comment, for the macOS run alone.
Verdict: Comment. The requested change is done, and done correctly. The new expects can fire on only one platform, and that platform still has no run of this head in this repo.
Needs the maintainer
- Add the
ci:macoslabel. The only CI run at7d9968c(36818218728) showsBuild (macOS)andBuild (Windows)asskipping. On Linux both GL binaries finish in about 0.05 s. That is consistent with the no-context skip, sobackend/tests/vision_mixer_fx_test.rs:142—.expect("GPU vision mixer pipeline builds");and:409have still never executed here. The alternative is to merge on Linux green and let the macOS build onmainbe the first real run. That is a legitimate call, but if the GPU mixer is broken on macOS today, that build will go red after the merge rather than before it.
Claims
| Claim | Verdict | Evidence |
|---|---|---|
| Build/start failures used to skip; missing elements were folded into "no context"; block IDs collided on global overlay state | CONFIRMED |
CONFIRMED in my review of 2026-09-30 at aea811e. The rebase did not change these hunks' substance. |
| Missing GL elements now go through the shared skip gate | CONFIRMED |
backend/tests/common/mod.rs:48 — pub fn gl_elements_available(required: &[&str]) -> bool {. It asserts under STROM_REQUIRE_GL, then returns require_or_skip(&missing), so STROM_REQUIRE_GST_PLUGINS still applies. Both hand-rolled copies are gone. backend/tests/vision_mixer_fx_test.rs:73 — if !common::gl_elements_available(&["glvideomixerelement", "glshader", "gltestsrc"]) {. Both files include it as pub mod common;, which is the form the module's header asks for, so it does not trip dead-code warnings. |
| The new failures fire on revert | UNVERIFIED |
Only on the author's runs. This repo has no macOS run at 7d9968c. |
Radius: LOCAL. The changes are test files plus one additive helper. The helper has no callers outside these two binaries.
Overlaps: #809, #806 and #803 still edit backend/tests/vision_mixer_fx_test.rs. These are textual conflicts only. No open PR touches backend/tests/common/mod.rs.
Tests & CI: At 7d9968c (run 36818218728), Check (Linux), both Linux builds, WASM and API Contract are green. Job 110227881429 shows all four GL tests ok, at Linux-skip timings.
Confidence: HIGH
…itch This branch now uses common::gl_elements_available from Eyevinn#917. Once Eyevinn#917 is on main, its commits drop out of this PR's diff.
… helper The resize tests had their own copy of the GL skip check, which folded missing GL elements into "no GL context". Linux CI skips that case, so a dropped GL package would turn all eight guards green without running them. Check the elements with common::gl_elements_available from Eyevinn#917 first, and keep the context probe for the legitimate headless skip. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Ran on macOS (aarch64, GStreamer 1.28.6) with
The last row is the hole this closes. Not run: clippy and the full suite. The break was local only and reverted. Merging. #894 now uses Claude (AI), on behalf of @srperens. |
* fix(vision mixer): keep a source's new shape when it changes size The GPU mixer's per-input glshader (fx_look, fx_take) takes its output size from the first entry of downstream's caps. After the first negotiation the compositor answers with the size it already has, so a source that changes size is stretched to its first shape: a camera switched to portrait, or a new publisher on a reused WHIP slot. The mixer never sees a caps change and never re-fits the aspect. Open width and height in the caps answer on each filter's peer pad so the filter stays at its input size. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(vision mixer): re-fit an input only once its new caps are stored The caps probe queues a geometry refresh on the main loop, which runs on its own thread. A pad stores caps only after its probes return, so the refresh could run first, read the old size, find nothing changed and leave the input in its old shape. Requeue the refresh until the pad holds the caps that triggered it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(vision mixer): re-fit from stored caps and the configured PGM size Refresh an input's geometry from the pad's notify::caps, which fires after the pad stores new caps, instead of a caps event probe that fires before. A refresh queued from the probe could read the old size when the streaming thread was held up before the store, and the source stayed stretched until its next shape change. This replaces the bounded requeue. Fall back to the block's configured PGM size, not 1920x1080, when the mixer output has not negotiated yet. The first refresh runs before it has, so a source present at start was fitted to a 1080p canvas on any other PGM size and stayed misplaced. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(vision mixer): hold a re-fit until a take or FTB is over Re-fitting an input clears the pad's control bindings, so a source that changed size during a fade or wipe ended the transition as a cut. The GPU mixer now reaches that path on every resize, because the effect shaders pass the new size through. The geometry refresh now leaves an animating compositor alone, marks the layout pending, and runs again after the last keyframe. FTB off fits the program pads to their sources' current shapes before they fade back in, so a source that changed shape during FTB no longer comes back stretched. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(vision mixer): let Fade to Black play out on a slow mixer FTB wiped its alpha keyframes on a wall-clock timer, duration + 100 ms. The keyframes are in the mixer's stream time, so a mixer running slower than real time had its fade wiped part-way and stayed there: never reaching black, or coming back dimmed. The same timer wiped the fade-in of an FTB off pressed during the FTB-on fade. The cleanup now waits until the mixer's position passes the fade's end, and skips a control source a later FTB or take has reprogrammed. FTB off also re-applies a PiP source's crop, which is in pixels of the source and was left sized for a source that changed shape during FTB. The fade and FTB tests now time their checks by the mixer's clock instead of the wall clock. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(gl): fail instead of skipping when the GPU mixer breaks vision_mixer_fx_test printed SKIP and passed when the GPU vision mixer failed to build or start, even after the GL probe had proven the environment renders and even under STROM_REQUIRE_GL. A GPU mixer that stopped building passed green on the macOS job. Those paths now fail. Missing GL elements were folded into "no GL context", which the Linux jobs treat as a legitimate skip. Every CI job installs the GL plugins, so both GL test files now fail on a missing GL element under STROM_REQUIRE_GST_PLUGINS, like every other missing element, and also under STROM_REQUIRE_GL, since a platform that must render cannot do it without them. The two fx tests shared block ID "vmfx". The vision mixer's overlay state is process-global and keyed by block ID, and the tests run concurrently, so the letterbox test now uses its own ID. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(gl): route missing GL elements through the shared test helper Both GL test files hand-rolled the STROM_REQUIRE_GST_PLUGINS check that common::require_or_skip already owns. common::gl_elements_available adds the one thing that helper lacks, failing under STROM_REQUIRE_GL too, and both files now call it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(vision mixer): pass take indices through a helper that fits either signature #806 changes trigger_transition's input indices from usize to Option<usize>. idx() converts into whichever the method takes, so these tests compile whether #806 lands before or after this PR. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(vision mixer): route missing GL elements through the shared test helper The resize tests had their own copy of the GL skip check, which folded missing GL elements into "no GL context". Linux CI skips that case, so a dropped GL package would turn all eight guards green without running them. Check the elements with common::gl_elements_available from #917 first, and keep the context probe for the legitimate headless skip. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Per Enstedt <per.enstedt@eyevinn.se>
Opened by Claude (AI), on Peter Wagenet's account.
Closes three ways the GL tests pass green without testing anything.
vision_mixer_fx_testprintedSKIP: could not build GPU pipelineand returned, even though the GL probe had just shown the environment renders, and even underSTROM_REQUIRE_GL=1. So on the macOS job, the one that renders, a GPU vision mixer that stopped building passed. Both tests nowexpectthe build and the start.gstreamer1.0-glpackage would go unnoticed there.vision_mixer_fx_testandshader_validation_testnow check the elements separately, through a newcommon::gl_elements_available. It fails underSTROM_REQUIRE_GL, since a platform that must render cannot do it without them, and otherwise defers tocommon::require_or_skip, so a missing element fails underSTROM_REQUIRE_GST_PLUGINSlike every other. The no-context case still skips unlessSTROM_REQUIRE_GLis set."vmfx". The vision mixer's overlay state is process-global and keyed by block ID, and tests in one binary run concurrently. The letterbox test now uses"vmfx-letterbox".Tests run (macOS,
--features efp,nvidia, head7d9968c)STROM_REQUIRE_GST_PLUGINS=1 STROM_REQUIRE_GL=1 cargo test --test vision_mixer_fx_test --test shader_validation_test: 4 passed.libgstopengl),--no-fail-fast --nocapture:STROM_REQUIRE_GST_PLUGINS=1alone, orSTROM_REQUIRE_GL=1alone: all 4 tests fail, naming the missing elements.SKIP: required GStreamer elements missingand pass, as on a developer machine without GL.cargo clippy --all-targets --features efp,nvidia -- -D warnings: clean.Revert check, run on the previous head
aea811e(before the rebase; the GPU build/startexpects are unchanged since): made the"gpu"arm ofselect_backend(vision_mixer/elements.rs) always return its error.SKIP: could not build GPU pipelineand pass.Fork CI with macOS dispatched, on
7d9968c(run). It does not show as a check here:STROM_REQUIRE_GL=1andSTROM_REQUIRE_GST_PLUGINS=1.vision_mixer_fx_testtook 15.4 s andshader_validation_testabout 2.6 s, so both rendered.aea811e(run): "Run tests" passed withSTROM_REQUIRE_GST_PLUGINS=1, so the MSI does install the GL elements. Both GL binaries stopped at the no-context skip, as before this PR. Not rerun on this head.Linux, from the same run's
Check (Linux)job: both GL binaries pass withSTROM_REQUIRE_GST_PLUGINS=1in 0.03 s. So the GL elements are installed, and the tests stop at the no-context skip, as before.Not run:
Overlap
#809, #806 and #803 also edit
vision_mixer_fx_test.rs, #809 heavily. Whichever lands second needs a small rebase.🤖 Generated with Claude Code