a4c84ac620
Decode+present rewrite (first real pixels on glass for this client): - Decode: FFmpeg D3D11VA on NVIDIA/AMD/Intel. get_format now only returns AV_PIX_FMT_D3D11 and lets libavcodec build the decode pool from hw_device_ctx (hand-built frames contexts failed three different ways: NVIDIA rejects DECODER|SHADER_RESOURCE arrays, BindFlags=0 fails texture creation, Intel rejects non-128-aligned HEVC surfaces at the first SubmitDecoderBuffers). A DXVA profile probe before the hwdevice commits hardware-vs-software up front instead of burning the opening IDR; extra_hw_frames covers the frames the client holds. - Present: the decoded slice is copied with ONE display-size-boxed CopySubresourceRegion (a planar slice is a single subresource in D3D11; the old two-copy D3D12-style code silently no-opped - the black screen) into a sampleable NV12/P010 texture, per-plane SRVs + YUV->RGB shaders. - New dedicated render thread (render.rs): presenting is decoupled from the XAML thread; frame-latency-waitable swapchain + SetMaximumFrameLatency(1), newest-wins drain after the wait, crossbeam frame channel with pts for a capture->presented p50 log. - HiDPI: pixel-sized buffers + SetMatrixTransform(96/dpi) - was blurry at 125/150 % scaling. - Software fallback now feeds the same shaders (swscale -> NV12/P010 planes -> two dynamic plane textures); ps_rgba/X2BGR10 path deleted, hw/sw colour math identical. - Adapter selection for hybrid boxes: PUNKTFUNK_ADAPTER > the window's monitor's adapter > default; PUNKTFUNK_D3D_DEBUG=1 debug layer. - Session pump: request_keyframe at start and on hw->sw demotion (infinite GOP would otherwise sit on a black screen). Validated live on the Arc Pro + RTX 3500 Ada laptop against the local Windows host: 60 fps D3D11VA on both vendors, software path, GUI on glass. Also: embedded app icon (build.rs winresource + WM_SETICON, MSIX Square44x44 targetsize assets, pack-msix stages them) and the hosts-page tile rework (tap-to-connect tiles with sibling overflow menu - fixes forget-also-connects - in-tile rename editor, add-host modal via root state). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
74 lines
3.3 KiB
TOML
74 lines
3.3 KiB
TOML
[package]
|
|
name = "punktfunk-client-windows"
|
|
description = "Native Windows punktfunk/1 client — WinUI 3 (windows-reactor) shell, D3D11/SwapChainPanel present, FFmpeg decode, WASAPI audio, SDL3 gamepads"
|
|
version.workspace = true
|
|
edition.workspace = true
|
|
rust-version.workspace = true
|
|
license.workspace = true
|
|
authors.workspace = true
|
|
repository.workspace = true
|
|
|
|
[[bin]]
|
|
name = "punktfunk-client"
|
|
path = "src/main.rs"
|
|
|
|
# Everything is Windows-gated so `cargo build --workspace` stays green on Linux/macOS (the
|
|
# other native clients live in clients/linux and clients/apple); on other
|
|
# platforms this builds as a stub binary. Mirrors the Linux client's cfg(target_os="linux")
|
|
# gating exactly.
|
|
[target.'cfg(windows)'.dependencies]
|
|
# The protocol core, linked directly (no C ABI) — same as the GTK Linux client. NativeClient
|
|
# is Sync (mutexed plane receivers), so it drops into a UI app cleanly.
|
|
punktfunk-core = { path = "../../crates/punktfunk-core", features = ["quic"] }
|
|
|
|
# WinUI 3 UI via windows-reactor (a declarative React-like framework backed by WinUI). Its
|
|
# `build.rs` downloads the Windows App SDK NuGets and stages the bootstrap DLL + resources.pri
|
|
# next to the exe; it requires `CARGO_WORKSPACE_DIR` to be set in the build env. Unpublished
|
|
# (version 0.0.0) and fast-moving, so pinned to a verified commit.
|
|
windows-reactor = { git = "https://github.com/microsoft/windows-rs", rev = "b4129fcc1ae81eec8bf1217539883db821bca3a1" }
|
|
# Win32 / Direct3D11 / DXGI for the SwapChainPanel composition swapchain. Pulled from the SAME
|
|
# windows-rs commit as windows-reactor so their `windows-core` unifies — the `IDXGISwapChain1`
|
|
# we hand to `SwapChainPanelHandle::set_swap_chain` must satisfy reactor's `windows_core::Interface`.
|
|
windows = { git = "https://github.com/microsoft/windows-rs", rev = "b4129fcc1ae81eec8bf1217539883db821bca3a1", features = [
|
|
"Win32_Foundation",
|
|
"Win32_Graphics_Dxgi",
|
|
"Win32_Graphics_Dxgi_Common",
|
|
"Win32_Graphics_Direct3D",
|
|
"Win32_Graphics_Direct3D11",
|
|
"Win32_Graphics_Direct3D_Fxc",
|
|
"Win32_Graphics_Gdi",
|
|
"Win32_System_Console",
|
|
"Win32_System_LibraryLoader",
|
|
"Win32_System_Threading",
|
|
"Win32_UI_HiDpi",
|
|
"Win32_UI_Input_KeyboardAndMouse",
|
|
"Win32_UI_WindowsAndMessaging",
|
|
] }
|
|
|
|
# Video decode (same FFmpeg pin as the host/Linux client) — software HEVC on the GPU-less dev
|
|
# box; D3D11VA hardware decode is a follow-up for the real-GPU box.
|
|
ffmpeg-next = "8"
|
|
opus = "0.3"
|
|
|
|
# Audio render + mic capture (the WASAPI analogue of the Linux client's PipeWire backend).
|
|
wasapi = "0.23"
|
|
|
|
# Gamepads: capture + feedback (full DualSense fidelity needs hidapi). SDL3 is cross-platform;
|
|
# built from source via the bundled CMake on Windows (no system SDL3).
|
|
sdl3 = { version = "0.18", features = ["build-from-source", "hidapi"] }
|
|
|
|
mdns-sd = "0.20"
|
|
async-channel = "2"
|
|
# The decoded-frame channel (session pump → render thread): crossbeam because the render loop
|
|
# blocks with `recv_timeout`, which async-channel has no sync analogue of.
|
|
crossbeam-channel = "0.5"
|
|
serde = { version = "1", features = ["derive"] }
|
|
serde_json = "1"
|
|
anyhow = "1"
|
|
tracing = "0.1"
|
|
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
|
|
|
# Embeds the app icon as an exe resource (build.rs) — Windows hosts only (rc.exe from the SDK).
|
|
[target.'cfg(windows)'.build-dependencies]
|
|
winresource = "0.1"
|