From 5f84c5785c043244645daed87ae201829f61b39e Mon Sep 17 00:00:00 2001 From: enricobuehler Date: Tue, 16 Jun 2026 14:08:59 +0000 Subject: [PATCH] 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 --- crates/punktfunk-host/src/m3.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/crates/punktfunk-host/src/m3.rs b/crates/punktfunk-host/src/m3.rs index 313d3b7..3dd59db 100644 --- a/crates/punktfunk-host/src/m3.rs +++ b/crates/punktfunk-host/src/m3.rs @@ -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.