Files
punktfunk/crates/pf-capture/Cargo.toml
T
enricobuehlerandClaude Fable 5 2e6cd0e235
ci / web (push) Successful in 2m30s
ci / docs-site (push) Successful in 2m49s
apple / swift (push) Successful in 4m36s
ci / rust-arm64 (push) Successful in 10m10s
docker / builders (--build-arg FEDORA_VERSION=44, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm, -f44) (push) Successful in 6s
docker / builders (ci/android-ci.Dockerfile, punktfunk-android-ci) (push) Successful in 5s
docker / builders (ci/arch-ci.Dockerfile, punktfunk-arch-ci) (push) Successful in 4s
docker / builders (ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 5s
docker / builders (ci/rust-ci-noble.Dockerfile, punktfunk-rust-ci-noble) (push) Successful in 5s
docker / builders (ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 5s
docker / apps (., web/Dockerfile, punktfunk-web) (push) Successful in 43s
docker / apps (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 9s
android / android (push) Successful in 12m44s
deb / build-publish (push) Successful in 11m34s
docker / builders-arm64cross (push) Successful in 23s
windows-drivers / probe-and-proto (push) Successful in 29s
docker / deploy-docs (push) Successful in 30s
arch / build-publish (push) Successful in 15m48s
ci / rust (push) Successful in 16m21s
windows-drivers / driver-build (push) Successful in 1m46s
deb / build-publish-client-arm64 (push) Successful in 9m22s
deb / build-publish-host (push) Successful in 19m7s
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Canceled after 12m34s
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Canceled after 11m40s
apple / screenshots (push) Successful in 20m22s
windows-host / package (push) Successful in 14m39s
windows-host / winget-source (push) Skipped
feat(capture): stall attribution phases A.2+A.3 — micro-probes and DxgKrnl ETW name the class
Phase A.2: a refcounted micro-probe engine (fence round-trip per adapter,
DwmGetCompositionTimingInfo tick, watchdogged DwmFlush, Level-Zero
D3DKMTGetScanLine, CPU jitter sentinel) samples continuously on detached
sacrificial threads; each stall report reads the window back and the verdict
matrix folds it with the driver telemetry into a named class: ours-worker /
ours-delivery / CLASS-1 adapter freeze / CLASS-2 compositor blocked /
frame-generation / unattributed. The metronomic WARN carries the per-class
session tally.

Phase A.3: an event-id-filtered real-time ETW session on
Microsoft-Windows-DxgKrnl (QueryChildStatus 150/151, SetPowerState 154/155,
IndicateChildStatus 272, SetTimingsFromVidPn 430, DisplayDetectControl
1096/1097) rides every stall line as a DDI bracket summary — naming the
servicing call and its duration instead of 'below Windows'. Degrades to
etw=unavailable without admin; probes degrade per-leg (absence is stated,
never guessed).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-29 23:44:35 +02:00

68 lines
3.0 KiB
TOML

# Frame capture (plan §7 / §W6): the Linux xdg-ScreenCast/PipeWire portal capturer and the Windows
# IDD direct-push capturer, plus the synthetic sources + the Capturer trait, extracted into a
# subsystem crate. Depends on the shared frame vocabulary (pf-frame), the zero-copy plumbing
# (pf-zerocopy), and the display leaves (pf-win-display) — never on pf-encode: the encode-backend
# facts arrive pre-resolved (ZeroCopyPolicy) and the sealed-channel delivery as a closure
# (FrameChannelSender), so the capture→encode edge is one-way (plan §2.4).
[package]
name = "pf-capture"
version.workspace = true
edition = "2021"
rust-version.workspace = true
license = "MIT OR Apache-2.0"
description = "punktfunk host frame capture: Linux PipeWire portal + Windows IDD direct-push capturers behind one Capturer trait."
publish = false
[dependencies]
punktfunk-core = { path = "../punktfunk-core", features = ["quic"] }
pf-frame = { path = "../pf-frame" }
pf-zerocopy = { path = "../pf-zerocopy" }
pf-win-display = { path = "../pf-win-display" }
pf-gpu = { path = "../pf-gpu" }
pf-host-config = { path = "../pf-host-config" }
anyhow = "1"
tracing = "0.1"
[target.'cfg(target_os = "linux")'.dependencies]
# The xdg ScreenCast + RemoteDesktop portals, and the PipeWire consumer for the capture frames.
ashpd = { version = "0.13", features = ["screencast", "remote_desktop"] }
pipewire = "0.9"
libc = "0.2"
# ashpd 0.13 uses the tokio runtime for the one-time portal handshake (control plane).
tokio = { version = "1", features = ["rt", "rt-multi-thread", "net", "time"] }
# XFixes cursor source for gamescope (remote-desktop-sweep Phase C): gamescope paints no
# `SPA_META_Cursor`, so the pointer never reaches the PipeWire node. We read the shape/hotspot/
# visibility from gamescope's nested Xwayland via XFixes instead and feed the existing cursor slot.
# `RustConnection` is the pure-Rust default (no libxcb link → no new C dependency on the host); the
# `xfixes` feature (auto-pulls `render` + `shape`) is what exposes GetCursorImage/SelectCursorInput.
x11rb = { version = "0.13", default-features = false, features = ["xfixes"] }
[target.'cfg(target_os = "windows")'.dependencies]
# The host<->driver wire contract for the sealed frame channel (control IOCTL structs + frame header).
pf-driver-proto = { path = "../pf-driver-proto" }
windows = { version = "0.62", features = [
"Win32_Foundation",
"Win32_Security",
"Win32_Security_Authorization",
"Win32_Graphics_Direct3D",
"Win32_Graphics_Direct3D11",
"Win32_Graphics_Direct3D_Fxc",
"Win32_Graphics_Dwm",
"Win32_Graphics_Dxgi",
"Win32_Graphics_Dxgi_Common",
"Win32_Graphics_Gdi",
"Win32_System_Diagnostics_Etw",
"Win32_System_LibraryLoader",
"Win32_System_StationsAndDesktops",
"Win32_System_Memory",
"Win32_System_Performance",
"Win32_System_Threading",
"Win32_System_Time",
"Win32_UI_HiDpi",
"Win32_UI_Input_KeyboardAndMouse",
"Win32_UI_WindowsAndMessaging",
] }
[lints]
workspace = true