feat(windows-host): SessionPlan — resolve capture/topology/encoder once per session (Goal-1 stage 3)
New src/session_plan.rs: a Copy `SessionPlan { capture, topology, encoder, bit_depth, hdr }`
resolved ONCE from HostConfig (+ the negotiated bit_depth) at the top of `virtual_stream`,
logged, and threaded through build_pipeline_with_retry/build_pipeline. The three scattered
Windows dispatch points now read this one typed artifact instead of re-deriving from config
(plan §2.4, the "capture and encode disagree on the backend" hazard):
* capture: capture::capture_virtual_output takes a CaptureBackend IN (was re-reading
config().idd_push / capture_backend / no_wgc internally). CaptureBackend::resolve() is the
single resolver, shared with the GameStream + spike call sites.
* topology: virtual_stream reads plan.topology; should_use_helper is deleted (its body is
session_plan::resolve_topology, verbatim). The IDD-push reconnect-preempt guard reads
plan.capture too.
* encoder: recorded as EncoderBackend from encode::windows_resolved_backend (config-backed +
GPU-vendor cached since stage 2 -> already a single source). Threading encoder/input_format
into the encoder+capturer opens (which removes the capture->windows_resolved_backend()
back-reference recomputed in dxgi.rs) is stage 5.
Behavior-preserving by construction: each resolved decision is provably equivalent to the
pre-stage-3 reads (same config() + the same cached running_as_system()/GPU-vendor probes), so
old==new. SessionPlan is platform-neutral so it threads the shared virtual_stream/build_pipeline
signatures; on Linux it resolves to the single portal/single-process path.
Also fixes a pre-existing mod-ordering fmt drift in main.rs (mod config; / mod capture;).
Verified: Linux cargo check + clippy (-D warnings) + fmt clean on the touched files. Box build
(Windows compile) + on-glass (NVENC + IDD-push + mode switch) pending on the RTX box.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -44,12 +44,23 @@ classes of `env::var` read are deliberately **kept live** and documented in `con
|
||||
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
|
||||
`SessionPlan`; replace the 3-place dispatch (`capture_virtual_output`, `should_use_helper`/`virtual_stream`,
|
||||
`windows_resolved_backend`) with reads off the plan. Fixes the capture/encode backend-disagreement bug
|
||||
class. Risk: medium-high (rewires the deployed decision). Verify: box build + on-glass re-test (NVENC +
|
||||
IDD-push + a mode switch).
|
||||
**Stage 3 — `SessionPlan` (the single biggest clarity lever, plan §2.4). ✅ IMPLEMENTED (this commit; on-glass pending).**
|
||||
New `src/session_plan.rs`: a `Copy` `SessionPlan { capture, topology, encoder, bit_depth, hdr }` resolved
|
||||
**once** from `HostConfig` (+ the negotiated `bit_depth`) in `virtual_stream`, logged, and threaded through
|
||||
`build_pipeline_with_retry`/`build_pipeline`. The three dispatch points now read it:
|
||||
- **capture** — `capture::capture_virtual_output` takes a `CaptureBackend` IN (was re-deriving from
|
||||
`config().idd_push`/`capture_backend`/`no_wgc`); `CaptureBackend::resolve()` is the one resolver (also
|
||||
used by the GameStream + spike call sites).
|
||||
- **topology** — `virtual_stream` reads `plan.topology` (`should_use_helper` deleted; its logic is
|
||||
`session_plan::resolve_topology`, verbatim). The IDD-preempt guard reads `plan.capture` too.
|
||||
- **encoder** — recorded as `EncoderBackend` from `encode::windows_resolved_backend` (config-backed +
|
||||
GPU-vendor cached since stage 2, already a single source). Threading `encoder`/`input_format` into the
|
||||
encoder + capturer opens (which removes the `dxgi.rs` back-reference) is **stage 5**.
|
||||
|
||||
Every decision is provably equivalent to the pre-stage-3 scattered reads (same `config()` + cached probes),
|
||||
so it is behavior-preserving. Risk: medium-high (rewires the deployed decision). Verify: box build (Windows
|
||||
compile, which also covers stage 2's Windows-only edits) + on-glass re-test (NVENC + IDD-push + a mode
|
||||
switch) — **pending** (RTX box `192.168.1.173`).
|
||||
|
||||
**Stage 4 — `SessionContext` + `SessionFactory`/`Session`.**
|
||||
Bundle the 12–13-arg `#[allow(too_many_arguments)]` signatures into `SessionContext`; `SessionFactory.build()`
|
||||
|
||||
Reference in New Issue
Block a user