From 3e2888de269ec1bf8b5867f7550739182eafa9f7 Mon Sep 17 00:00:00 2001 From: enricobuehler Date: Tue, 16 Jun 2026 10:22:53 +0000 Subject: [PATCH] docs(apollo): mark GSO #4 (GameStream Windows USO) done Co-Authored-By: Claude Opus 4.8 --- docs/apollo-comparison.md | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/docs/apollo-comparison.md b/docs/apollo-comparison.md index 90537c4..b00974b 100644 --- a/docs/apollo-comparison.md +++ b/docs/apollo-comparison.md @@ -1608,7 +1608,7 @@ adversarial-verify pass. *Area* is the investigation that surfaced it. | 1 | Switch SendInput to retry-on-failure desktop reattach (drop per-event OpenInputDesktop) | cmp:input | Y | high | small | | | 2 | Detect resolution/format change on the acquire hot path, not only during rebuild | win:capture-dxgi-dd | Y | high | small | | | 3 | Per-frame IsCurrent() check to catch HDR/GPU/mode changes | win:capture-wgc | Y | high | small | | -| 4 | Batched/GSO send for the GameStream video plane on Windows | cmp:protocol-streaming | Y | high | medium | ✓ | +| 4 | ✅ **DONE** — Batched/GSO send for the GameStream video plane on Windows | cmp:protocol-streaming | Y | high | medium | ✓ | | 5 | Gate the GameStream HTTPS plane on the paired-cert allow-list | cmp:gamestream-http-pairing | Y | high | medium | | | 6 | Query NVENC encode capabilities before init and degrade gracefully | cmp:video-encode | Y | high | medium | | | 7 | Detect default-render-device changes and reinit WASAPI capture | cmp:audio | Y | high | medium | | @@ -1727,7 +1727,16 @@ adversarial-verify pass. *Area* is the investigation that surfaced it. - **Proposal:** Hold an IDXGIFactory1 in WgcCapturer (from the same adapter as make_device) and call IsCurrent() at the top of next_frame/wait_and_drain; on false, return the reinit signal. This pairs with wgc-size-format-reinit to give a complete change-detection story. #### 4. Batched/GSO send for the GameStream video plane on Windows -*Area:* `cmp:protocol-streaming` · *Windows-host:* yes · *Severity:* high · *Effort:* medium · **✓ verified** +*Area:* `cmp:protocol-streaming` · *Windows-host:* yes · *Severity:* high · *Effort:* medium · **✓ verified · ✅ DONE (2026-06-16)** + +> **Resolution:** Implemented per the refined proposal. Added a reusable Windows-only +> `punktfunk_core::transport::send_uso_all(&UdpSocket, &[&[u8]]) -> io::Result` that reuses the +> native plane's proven `send_one_uso` + `uso` on/off latch + `uso_unsupported`, with the same +> uniform-size guard and ≤512-segment chunking. `gamestream/stream.rs` `sendmmsg_all` now has a +> `#[cfg(target_os="windows")]` arm that calls it per 16-packet paced burst (one `WSASendMsg` instead +> of 16 `send`s) and sends any remainder scalar; the Linux `sendmmsg` arm and a generic scalar arm are +> unchanged. PUNKTFUNK_GSO=0 kill-switch + auto-fallback inherited. Linux build unaffected; +> punktfunk-core type-checks for x86_64-pc-windows-msvc. Host Windows compile deferred to CI/dev box. - **Apollo does:** Apollo sends every plane through platf::send_batch / send (one code path for all OSes; on Windows it uses real batched socket writes), and the video broadcast thread is the single transmit path (stream.cpp:1327, send batching at stream.cpp:1337 send_batch latency logger). - **punktfunk gap:** The GameStream video sender's batched path is Linux-only: sendmmsg_all has a #[cfg(target_os="linux")] real implementation (stream.rs:147) and a #[cfg(not(target_os="linux"))] fallback that does one sock.send() per packet (stream.rs:185-191). On a Windows GameStream-compat host (capture IS wired for Windows via DXGI/WGC, capture.rs:261) every video datagram is an individual syscall — the native punktfunk/1 plane got Windows USO (transport/udp.rs:135) but the GameStream plane did not.