feat(windows): IddCx hardware-cursor channel — remote-desktop sweep M2c
Brings the cursor channel to Windows hosts. The pf-vdisplay driver declares an IddCx hardware cursor for sessions that negotiated cursor-forward — DWM then EXCLUDES the pointer from the IDD frame and delivers shape/position out-of-band, into the same CursorOverlay → forwarder → wire → client pipeline the Linux portal path uses. - pf-driver-proto v5 (additive, host floor stays 3): AddRequest's spare tail becomes hw_cursor (same size/offsets); IOCTL_SET_CURSOR_CHANNEL delivers a host-created CursorShm section (64-byte seqlock header + 256² shape buffer, layout pinned + tested). No event crosses the boundary — the host polls at encode-tick pace. - driver: wdk-iddcx grows the two cursor DDI wrappers; a per-monitor cursor worker (event wait → QueryHardwareCursor → seqlock publish) starts only when BOTH the ADD asked and the channel arrived, so a failed delivery leaves DWM compositing as today. Shape bytes ship raw (BGRA/masked + pitch); the host converts. - host: the section rides the existing sealed-channel broker (least- privilege dup, remote reap on failure); IddPushCapturer::cursor() seqlock-reads → CursorOverlay (BGRA→RGBA, masked-color approximation, desktop→frame origin shift, per-shape conversion cache). New Capturer::cursor() trait hook — the encode loop prefers it over the frame-attached overlay because hardware-cursor moves produce NO new frame on a static desktop. hw_cursor survives the re-arrival resize (carried on the manager's Monitor). - negotiation: cursor_forward grows the Windows arm (client cap ∧ driver proto ≥ 5, probed once via the control device); SessionPlan carries cursor_forward → OutputFormat.hw_cursor. - drive-by: wdk-probe's two pre-existing same-type casts (clippy) and pf-vdisplay's stale spike-test refs (crate::win_display moved to pf-win-display; tracing-subscriber was never a dep) repaired. Verified: proto tests on Mac AND MSVC (15/15 incl. the CursorShm layout pin); clippy -D warnings for proto/frame/capture/vdisplay/host on Linux (.21) and native Windows (.173); the DRIVER workspace clippy -D warnings green against the real WDK 10.0.26100 bindgen (DDI names, enum variants and IDARG layouts all bind). On-box driver deploy + on-glass validation follow. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -152,6 +152,12 @@ pub struct OutputFormat {
|
||||
/// codec's backend, and the fallback family) would misread the two-plane buffer as packed
|
||||
/// RGB. Always `false` on Windows (the IDD-push capturer owns its own formats).
|
||||
pub nv12_native: bool,
|
||||
/// The session negotiated the cursor-forward channel (remote-desktop-sweep M2c): on Windows
|
||||
/// the IDD-push capturer creates + delivers the driver's hardware-cursor section, so DWM
|
||||
/// stops compositing the pointer into the frames and the capturer surfaces it via
|
||||
/// `Capturer::cursor()` instead. Ignored on Linux (the portal's `SPA_META_Cursor` already
|
||||
/// separates the pointer; the session plan's `cursor_blend` gate handles the rest).
|
||||
pub hw_cursor: bool,
|
||||
}
|
||||
|
||||
impl OutputFormat {
|
||||
@@ -169,6 +175,8 @@ impl OutputFormat {
|
||||
chroma_444: false,
|
||||
// GameStream never negotiates PyroWave (native punktfunk/1 only).
|
||||
pyrowave: false,
|
||||
// GameStream/spike sessions never negotiate the cursor channel.
|
||||
hw_cursor: false,
|
||||
// Conservative: the GameStream + spike paths don't resolve the codec here, and a
|
||||
// Moonlight client may negotiate H264 (whose VAAPI backend can't ingest NV12) — so
|
||||
// they never prefer the producer-native NV12 pod. The punktfunk/1 plane opts in via
|
||||
|
||||
Reference in New Issue
Block a user