feat(windows-host): OutputFormat into the capturer — kill the dxgi back-reference (Goal-1 stage 5, tightening 1)
The headline §2.3 seam tightening (the explicit Stage-3 deferral; §5's "highest-severity
coupling"): the capturer is now TOLD its output format instead of re-deriving the encode backend.
New `capture::OutputFormat { gpu, hdr }`, resolved once per session and passed INTO
capture_virtual_output:
* native punktfunk/1 path: `SessionPlan::output_format()` (gpu = encoder.is_gpu(), from the
already-resolved plan.encoder — no second probe; hdr = plan.hdr).
* GameStream + spike paths: `OutputFormat::resolve(hdr)` (gpu from the single `gpu_encode()`
source, which maps windows_resolved_backend()).
`capture/dxgi.rs DuplCapturer::open` takes `gpu` in and its internal
`!matches!(windows_resolved_backend(), Software)` recompute is DELETED — the capture layer no
longer re-calls the encode layer (the back-reference that could let capture and encode disagree
on whether frames are GPU-resident, plan §2.3/§5). The relay's secure-desktop DDA passes
`gpu_encode()` likewise.
Behavior-preserving: the `gpu` passed in equals the value the capturer used to compute (same
encode-backend resolution). The DDA opens keep `want_hdr=false` (the SDR fallback, unchanged).
Tightenings 2 (HDR/release -> VirtualLease) and 3 (EncoderCaps) split off: (2) needs the
monitor-generation carried on the lease + the keepalive becoming Box<dyn VirtualLease> — that's
the §2.5 ownership-model change (CURRENT_MON_GEN / sudovda::wait_for_monitor_released), so it
moves there; (3) is a small additive follow-on. Documented in the plan.
Verified: Linux cargo check + clippy (-D warnings) + fmt clean. Box build to follow.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -91,11 +91,24 @@ explicit), and it is the validated shipping path. Wrapping the deployed reconfig
|
||||
the concrete, safe arg-bundling. Risk: low (behavior-identical). Verify: Linux + box build (the relay
|
||||
destructure is the only Windows-only piece); the teardown on-glass gate moves to the §2.5 work.
|
||||
|
||||
**Stage 5 — seam-trait tightenings (plan §2.3).**
|
||||
`Capturer::open_capturer(vout, want: OutputFormat)` takes the format IN (kills the
|
||||
`capture → encode::windows_resolved_backend()` back-reference recomputed in `dxgi.rs`); HDR/release become
|
||||
`VirtualLease` methods (session glue names no concrete backend, contains no `unsafe`); optional encoder
|
||||
features move to `EncoderCaps`. Risk: medium. Verify: box build + on-glass.
|
||||
**Stage 5 — seam-trait tightenings (plan §2.3). 🟡 Tightening 1 ✅ DONE (box-build validated); 2→§2.5, 3 follow-on.**
|
||||
The three §2.3 tightenings have different coupling, so they split:
|
||||
- **(1) `OutputFormat` into the capturer ✅** — the headline (the explicit Stage-3 deferral; §5's
|
||||
"highest-severity coupling"). New `capture::OutputFormat { gpu, hdr }`, resolved once per session and
|
||||
passed **into** `capture_virtual_output` (`SessionPlan::output_format()` for the native path —
|
||||
`gpu = encoder.is_gpu()`, no second probe; `OutputFormat::resolve()` for the GameStream/spike paths).
|
||||
`dxgi::DuplCapturer::open` takes `gpu` in and **its `windows_resolved_backend()` recompute is deleted** —
|
||||
capture no longer re-derives the encode backend. Behavior-preserving (the `gpu` passed in equals the value
|
||||
the capturer used to compute). Linux + box-build clean.
|
||||
- **(2) HDR/release → `VirtualLease`** — **moved to §2.5.** `await_released` as a lease method needs the
|
||||
monitor-generation carried *on the lease* (today it's the `CURRENT_MON_GEN` global + the
|
||||
`sudovda::wait_for_monitor_released` free fn), and the keepalive becoming `Box<dyn VirtualLease>` is the
|
||||
ownership-model change. It belongs with the `VirtualDisplayManager`/`MonitorLease` work, not bolted on here.
|
||||
- **(3) `EncoderCaps`** — small additive follow-on (query optional encoder capabilities instead of default
|
||||
no-ops); not blocking. Tracked for the next seam pass.
|
||||
|
||||
Risk: medium (Tightening 1 is behavior-preserving + Windows-only → box-compile is the gate; on-glass parity is
|
||||
the same env-limited story as Stage 3).
|
||||
|
||||
**Stage 6 — `src/windows/` tree (cfg-sprawl confinement, plan §2.2).**
|
||||
Move the Windows backends under `src/windows/` + `capture/windows/`, `encode/windows/`, `inject/windows/`,
|
||||
|
||||
Reference in New Issue
Block a user