fix(host/windows): force-composed-flip overlay in the single-process DDA path
CONFIRMED root cause via instrumented build: hook_hits=1+ (win32u hook fires, verified-patched) and DPI awareness=2 (PER_MONITOR), yet the born-lost ACCESS_LOST storm persists with 100% DuplicateOutput1 E_ACCESSDENIED. That rules out reparenting (the hook works) and DPI -> it is fullscreen independent-flip / MPO: the SudoVDA virtual display, isolated as the SOLE active output, scans out one plane on one display, bypassing DWM composition, so Desktop Duplication gets a born-lost duplication. Apollo never hits this because it runs WITH a physical monitor attached (multi-display is already DWM-composited); we isolate to sole-display, so we must force composition ourselves. The fix already existed (ForceComposedFlip, a tiny topmost layered overlay that disqualifies independent-flip) but was only wired into the WGC relay path's secure branch, which PUNKTFUNK_NO_WGC=1 disables. Wire it into virtual_stream unconditionally (DDA owns the normal desktop here, where the storm is). Held for the session; Drop tears it down; PUNKTFUNK_FORCE_COMPOSED=0 disables. Keeps the prior build's born-lost escape as a safety net. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -2026,6 +2026,19 @@ fn virtual_stream(
|
||||
let (mut capturer, mut enc, mut frame, mut interval) =
|
||||
build_pipeline_with_retry(&mut vd, mode, bitrate_kbps, bit_depth)?;
|
||||
|
||||
// Windows single-process DDA path (PUNKTFUNK_NO_WGC=1): the SudoVDA virtual display, isolated as the
|
||||
// SOLE active output, goes into fullscreen independent-flip (one plane on one display) which Desktop
|
||||
// Duplication cannot capture → the born-lost ACCESS_LOST storm we measured on the RTX4090+iGPU box
|
||||
// (hook verified-firing, DPI=2, yet 100% DuplicateOutput1 E_ACCESSDENIED + born-lost). A tiny topmost
|
||||
// layered overlay disqualifies independent-flip and forces DWM composition, which DDA CAN capture.
|
||||
// (Apollo never hits this because it runs WITH a physical monitor attached — multi-display is already
|
||||
// DWM-composited; we isolate to sole-display, so we must force composition ourselves.) Unlike the WGC
|
||||
// relay path — where WGC owns the normal desktop and the overlay is secure-only — here DDA owns the
|
||||
// normal desktop too, so it must run unconditionally. Held for the session; Drop tears it down.
|
||||
// Best-effort; disable with PUNKTFUNK_FORCE_COMPOSED=0.
|
||||
#[cfg(target_os = "windows")]
|
||||
let _composed_flip = crate::capture::composed_flip::ForceComposedFlip::start();
|
||||
|
||||
let perf = std::env::var("PUNKTFUNK_PERF").is_ok();
|
||||
// Microburst cap (applied in send_loop/paced_submit): a frame ≤ this bursts out immediately;
|
||||
// only a bigger frame's overflow is spread. PUNKTFUNK_PACE_BURST_KB overrides the 128 KB default.
|
||||
|
||||
Reference in New Issue
Block a user