feat(windows-host): finish HostConfig migration — resolve operator/dispatch knobs once (Goal-1 stage 2)

Migrate 31 genuinely-constant operator/dispatch env::var sites onto HostConfig, so the
capture/topology/encoder decision reads ONE owner instead of being recomputed at each call
site (the latent bug where capture and encode could disagree on the resolved backend, plan §2.4):
idd_push x7, no_wgc, capture_backend, render_adapter, encoder_pref (Linux open_video +
linux_zero_copy_is_vaapi), the Windows vdisplay-backend select, plus the plan-named
secure_dda/idd_depth/zerocopy/ten_bit and the multi-site perf x4 / compositor x5 /
video_source x3 / gamepad. Each HostConfig field's parser is byte-identical to the read it
replaced, so old==new by construction (the plan's "a flipped bool is a silent regression" guard).

Scope correction — the plan's "~64 sites / Linux XDG+compositor included / grep env::var -> 0"
was unsafe as written. Two classes are deliberately KEPT as live reads and documented in config.rs:

  * Runtime-mutated session vars. vdisplay::apply_session_env REWRITES the process env on every
    connect (the Bazzite Gaming<->Desktop follow): WAYLAND_DISPLAY, XDG_CURRENT_DESKTOP,
    XDG_RUNTIME_DIR, DBUS_SESSION_BUS_ADDRESS, and the derived PUNKTFUNK_INPUT_BACKEND,
    GAMESCOPE_SESSION/NODE, KWIN/MUTTER_VIRTUAL_PRIMARY, FORCE_SHM. Parsing these once would
    freeze them at startup and silently break session-following — they are NOT constant.
  * Single-use local tuning with no resolve-once benefit (and FEC_PCT even has two different
    semantics): FEC_PCT, VIDEO_DROP, VBV_FRAMES, SPLIT_ENCODE, PACE_BURST_KB, the dxgi timing
    knobs, the *_LIVE/test gates, plus path/dynamic reads (config-dir, PATH search,
    env-forward-to-child). PUNKTFUNK_ZEROCOPY is split on purpose: Windows presence-semantics
    moved to the field; Linux keeps its own truthy (1|true|yes|on) parser.

Verified: Linux cargo check + clippy (-D warnings) + fmt clean on the touched files. The
Windows-only edits are 1:1 substitutions; they get a real Windows compile on the box with Stage 3.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-25 17:24:00 +00:00
parent a3eefc2374
commit e5057f6cc1
14 changed files with 138 additions and 65 deletions
+22 -6
View File
@@ -21,12 +21,28 @@ Migrated the two highest-churn dispatch reads onto it (`encode::windows_resolved
`punktfunk1::should_use_helper`). Risk: low (env constant at runtime → identical behaviour). Verify: box
`cargo check --features nvenc`.
**Stage 2 — finish `HostConfig` + resolve-once.**
Migrate the remaining ~64 `env::var` sites onto `HostConfig` fields (esp. `PUNKTFUNK_IDD_PUSH` ×8,
`PUNKTFUNK_RENDER_ADAPTER`, `PUNKTFUNK_ZEROCOPY`, `PUNKTFUNK_SECURE_DDA`, `PUNKTFUNK_IDD_DEPTH`,
`PUNKTFUNK_NO_WGC`, the perf/debug flags). Linux vars (XDG/compositor) included for one config. Risk:
medium (must preserve each var's exact semantics — a flipped bool is a silent regression; assert per the §1
checklist). Verify: Linux + box build; `grep env::var` should reach ~0 outside `config.rs`.
**Stage 2 — finish `HostConfig` + resolve-once. ✅ DONE (this commit).**
Migrated **31** genuinely-constant operator/dispatch sites onto `HostConfig`: `idd_push` ×7 (the
capture/topology disagreement knob), `no_wgc`, `capture_backend`, `render_adapter`, `encoder_pref` (Linux),
the Windows vdisplay-backend select, plus the plan-named `secure_dda`/`idd_depth`/`zerocopy`/`ten_bit` and the
multi-site `perf` ×4 / `compositor` ×5 / `video_source` ×3 / `gamepad`. Each `HostConfig` field's parser is
**byte-identical** to the read it replaced, so `old == new` by construction (the §1 "flipped bool" guard).
**Scope correction (the plan's "~64 sites / Linux XDG+compositor / grep→0" was unsafe as written):** two
classes of `env::var` read are deliberately **kept live** and documented in `config.rs`:
- **Runtime-mutated session vars.** On Linux, `vdisplay::apply_session_env` *rewrites the process env on
every connect* (the Bazzite Gaming↔Desktop follow): `WAYLAND_DISPLAY`, `XDG_CURRENT_DESKTOP`,
`XDG_RUNTIME_DIR`, `DBUS_SESSION_BUS_ADDRESS`, and the derived `PUNKTFUNK_INPUT_BACKEND`,
`PUNKTFUNK_GAMESCOPE_SESSION/NODE`, `PUNKTFUNK_KWIN/MUTTER_VIRTUAL_PRIMARY`, `PUNKTFUNK_FORCE_SHM`.
Parse-once would freeze them at startup → silent session-following regression. They are NOT constant.
- **Single-use local tuning** (no resolve-once benefit, call-site-local default/clamp, and `FEC_PCT` even has
*two different* semantics): `FEC_PCT`, `VIDEO_DROP`, `VBV_FRAMES`, `SPLIT_ENCODE`, `PACE_BURST_KB`, the
`capture/dxgi.rs` timing knobs, the `*_LIVE`/test gates, plus path/dynamic reads (config-dir, `PATH`
search, env-forward-to-child). `PUNKTFUNK_ZEROCOPY` is split on purpose: Windows presence-semantics moved
to the field; Linux keeps its own truthy parser.
Risk: medium (semantics-preservation). Verify: Linux `cargo check`/`clippy`/`fmt` green (the Windows-only
edits are 1:1 substitutions, compile-verified on the box as part of Stage 3's build).
**Stage 3 — `SessionPlan` (the single biggest clarity lever, plan §2.4).**
Resolve `display/capture/topology/encoder/format/hdr/bit_depth` ONCE from `HostConfig` into a typed