fix(host/windows): WGC mux — reuse the SudoVDA monitor + helper across secure switches (no teardown/recreate)
User: re-adding WGC brought back the teardown/recreate bug (audible disconnect/ connect on the secure<->normal switch). Cause: the secure->normal switch called build() = vd.create() = IOCTL_REMOVE old SudoVDA monitor + IOCTL_ADD new one + respawn the helper — the same teardown/recreate kernel stress we just eliminated from DDA, now on the mux path. Apply the same learning (reuse, don't tear down): the SudoVDA monitor and WGC helper persist for the whole session; only the host-DDA leg opens (on secure) and closes (on normal). On returning to normal, RESUME the still-alive helper (drain its secure-dwell backlog + request a keyframe) instead of rebuilding. The HDR-session colorspace restore (set_advanced_color(true) + helper rebuild) is kept ONLY for bit_depth>=10 — an SDR session never changed the colorspace, so it needs no rebuild at all. The secure switch already reuses the monitor (open_dda on the existing target). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -2581,31 +2581,39 @@ fn virtual_stream_relay(
|
|||||||
}
|
}
|
||||||
next = std::time::Instant::now();
|
next = std::time::Instant::now();
|
||||||
} else {
|
} else {
|
||||||
// Returning to the normal desktop: restore HDR on the SudoVDA (HDR sessions ONLY — WGC
|
// Returning to the normal desktop: RESUME from the still-alive WGC helper. Do NOT
|
||||||
// then captures it HDR). An SDR (8-bit) session must stay SDR; forcing HDR here is what
|
// recreate the SudoVDA monitor or respawn the helper — build()'s vd.create() is an
|
||||||
// made the rebuilt WGC helper capture HDR FP16 BT.2020 while the encoder is 8-bit SDR →
|
// IOCTL_REMOVE+ADD of the monitor (the audible disconnect/connect chime + the
|
||||||
// format mismatch / broken image (the "HDR gets restored when flipping back" bug).
|
// teardown/recreate kernel stress that broke DDA, now applied to the mux). The monitor +
|
||||||
|
// helper persist for the WHOLE session; only the host-DDA leg opens (secure) and closes
|
||||||
|
// (normal). Apply the DDA learning here: reuse, don't tear down.
|
||||||
|
dda = None; // free the secure DDA encoder; the relay (helper) is the source again
|
||||||
|
while relay.try_recv().is_ok() {} // drop secure-dwell backlog
|
||||||
|
relay.request_keyframe(); // client decoder resumes on the helper's next IDR
|
||||||
if bit_depth >= 10 {
|
if bit_depth >= 10 {
|
||||||
|
// HDR session ONLY: the secure switch dropped the SudoVDA to SDR for the DDA leg, so
|
||||||
|
// here we must restore HDR AND rebuild the helper so WGC re-detects the HDR
|
||||||
|
// colorspace. An SDR session never changed the colorspace → no rebuild, no recreate.
|
||||||
unsafe {
|
unsafe {
|
||||||
crate::vdisplay::sudovda::set_advanced_color(target.target_id, true);
|
crate::vdisplay::sudovda::set_advanced_color(target.target_id, true);
|
||||||
}
|
}
|
||||||
}
|
match build(&mut vd, cur_mode) {
|
||||||
dda = None; // free the secure DDA encoder
|
Ok((ka, rl, tg, hz)) => {
|
||||||
match build(&mut vd, cur_mode) {
|
relay = rl;
|
||||||
Ok((ka, rl, tg, hz)) => {
|
_keepalive = ka;
|
||||||
relay = rl;
|
target = tg;
|
||||||
_keepalive = ka;
|
effective_hz = hz;
|
||||||
target = tg;
|
interval = std::time::Duration::from_secs_f64(1.0 / hz.max(1) as f64);
|
||||||
effective_hz = hz;
|
}
|
||||||
interval = std::time::Duration::from_secs_f64(1.0 / hz.max(1) as f64);
|
Err(e) => {
|
||||||
}
|
tracing::error!(error = %format!("{e:#}"),
|
||||||
Err(e) => {
|
"two-process: helper rebuild on secure-exit failed");
|
||||||
tracing::error!(error = %format!("{e:#}"),
|
while relay.try_recv().is_ok() {}
|
||||||
"two-process: helper rebuild on secure-exit failed");
|
relay.request_keyframe();
|
||||||
while relay.try_recv().is_ok() {}
|
}
|
||||||
relay.request_keyframe();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
next = std::time::Instant::now();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if want_kf {
|
if want_kf {
|
||||||
|
|||||||
Reference in New Issue
Block a user