apple / swift (pull_request) Successful in 1m20s
apple / screenshots (pull_request) Skipped
ci / web (pull_request) Successful in 1m14s
ci / docs-site (pull_request) Successful in 1m19s
android / android (pull_request) Successful in 5m33s
ci / rust-arm64 (pull_request) Successful in 5m21s
ci / rust (pull_request) Failing after 5m56s
windows / build (aarch64-pc-windows-msvc) (pull_request) Failing after 41s
windows / build (x86_64-pc-windows-msvc) (pull_request) Failing after 43s
A minor bump: 98 commits since v0.24.0. The headline is DualSense pad audio (PR #23) — a wired DualSense playing a game's voice-coil haptics and its own speaker, streamed from the host, on Android and the desktop session client against a Windows host with Steam's driver present. Behind it: the haptics sweep's twelve milestones closing more than twenty controller faults across every client and both hosts; the audio quality/latency work (256 kbps stereo, the Steam Streaming Microphone endpoint root cause, and the de-jitter ratchet that left audio permanently behind the picture); and MTU resilience plus mid-session shard renegotiation, which turns the silent all-black stream on a sub-1330-byte path into a diagnosed warning that heals itself. Plus the Decky plugin reduced to a launcher, system-button routing with hold-Select, gamepad-UI profiles on all three UIs, `discover`/`launch --request-access` in the CLI, and the Sunshine false-conflict and crashed-host display-restore fixes. The canary base is already 0.25 — scripts/ci/pf-version.sh derives it as one minor ahead of the latest stable tag — so this is the version canary has been publishing against all along. Wire protocol stays at 2: every addition this cycle is optional or capability-gated (an optional trailing max_shard_payload on Hello, the 0x08/0x09 renegotiation pair, the 0xD1 pad-audio plane, the 0xD2 redundant desktop-audio plane, MAX_DATAGRAM_BYTES 2048 -> 9216). C ABI moves 14 -> 16 in two steps: 15 retroactively declares the floor that guarantees the rumble policy engine's C surface (which shipped while the constant still read 7), and 16 adds the pad-audio surface and mirrors its two capability bits. Four new capability bits land in the client/host bytes (audio redundancy 0x04/0x20, pad audio 0x08/0x40); the video-caps byte was NOT touched and stays full from 0.23.0, so the standing "next video cap needs a second byte and an ABI bump" note still holds. host_caps is now down to its last free bit (0x80). Virtual-display driver protocol 6 and the Windows gamepad channel 3 are untouched — pf-driver-proto is byte-for-byte identical to v0.24.0. The generated header is in sync (ABI 16, both cap mirrors). Breaking for C embedders: 149 unprefixed macros are now PUNKTFUNK_-prefixed (139 #defines renamed in the checked-in header). Mechanical to fix, and it cannot break silently — the old spellings cease to exist, so it is always an undeclared-identifier error rather than the wrong value a colliding #define used to produce. Lock touched for the 32 workspace members only, via `cargo update --workspace`: diff against origin/main is versions-only, 32 insertions and 32 deletions. Unlike the last cut there is no third-party crate sitting on the outgoing version to trip the count — `wasapi` is at 0.23.0 and was never a candidate. `cargo metadata --locked` resolves (35 members; fec-rs, pf-driver-proto and usbip-sim keep their own versions by design). `cargo fmt --all --check` clean in both the main and packaging/windows/drivers workspaces. Doc lazy-continuation scanner: 0 hits over 521 files — that regex is the exact defect that made the first v0.23.0 tag go red on Windows clippy, and no Windows leg runs on a main push, so main being green proves nothing about the tag fan-out. api/openapi.json is deliberately left at 0.23.0: it tracks API edits and lags, as in every prior cut. It is now two releases behind and worth a look. Notes at docs/releases/v0.25.0.md, per docs/releases/README.md — authored with the bump so CI's ensure_release seeds the release body at tag creation. Body voice checked programmatically: 0 internal-vocabulary hits above `## Under the hood`. Play's "What's new" at docs/releases/whatsnew/v0.25.0.txt (494/500 chars), verified by running android.yml's gate logic verbatim against it, including the byte-identical-to-another-release check.
105 lines
4.7 KiB
TOML
105 lines
4.7 KiB
TOML
[workspace]
|
|
resolver = "2"
|
|
members = [
|
|
"crates/punktfunk-core",
|
|
"crates/punktfunk-host",
|
|
"crates/punktfunk-host/vendor/usbip-sim",
|
|
"crates/punktfunk-tray",
|
|
"crates/pf-client-core",
|
|
"crates/pf-clipboard",
|
|
"crates/pf-presenter",
|
|
"crates/pf-console-ui",
|
|
"crates/pf-ffvk",
|
|
"crates/pf-driver-proto",
|
|
"crates/pf-paths",
|
|
"crates/pf-update",
|
|
"crates/pf-update-check",
|
|
"crates/pf-host-config",
|
|
"crates/pf-gpu",
|
|
"crates/pf-zerocopy",
|
|
"crates/pf-frame",
|
|
"crates/pf-win-display",
|
|
"crates/pf-encode",
|
|
"crates/pf-capture",
|
|
"crates/pf-inject",
|
|
"crates/pf-vdisplay",
|
|
"crates/pyrowave-sys",
|
|
"crates/libvpl-sys",
|
|
"clients/probe",
|
|
"clients/cli",
|
|
"clients/linux",
|
|
"clients/session",
|
|
"clients/windows",
|
|
"clients/android/native",
|
|
"tools/cursor-probe",
|
|
"tools/display-disturb",
|
|
"tools/latency-probe",
|
|
"tools/loss-harness",
|
|
]
|
|
# Standalone PoC (built on its own; pulls usbip/tokio/libusb we don't want in the workspace).
|
|
# The vendored `ndk` is a [patch.crates-io] source, not a member: it only compiles for the
|
|
# `*-linux-android` targets, so workspace membership would break host `cargo build --workspace`.
|
|
exclude = [
|
|
"packaging/linux/steam-deck-gadget/usbip-poc",
|
|
"clients/android/native/vendor/ndk",
|
|
]
|
|
|
|
# ndk 0.9.0 verbatim from crates.io plus ONE visibility change (and two warning fixes — an
|
|
# unnecessary `std::` qualification and a feature-gated `Result` import): `MediaCodec::as_ptr` made public
|
|
# (upstream keeps it private and exposes no frame-rendered binding), so the Android client can
|
|
# call `AMediaCodec_setOnFrameRenderedCallback` via ndk-sys for the HUD's `display` stage
|
|
# (design/stats-unification.md). Drop the patch when upstream exposes the pointer or the callback.
|
|
[patch.crates-io]
|
|
ndk = { path = "clients/android/native/vendor/ndk" }
|
|
|
|
[workspace.package]
|
|
version = "0.25.0"
|
|
edition = "2021"
|
|
rust-version = "1.82"
|
|
license = "MIT OR Apache-2.0"
|
|
authors = ["unom"]
|
|
repository = "https://git.unom.io/unom/punktfunk"
|
|
|
|
# The `unsafe` discipline the `packaging/windows/drivers/*` crates already run, extended to the
|
|
# workspace. `unsafe fn` marks a CONTRACT the caller must uphold; it is not a licence for the whole
|
|
# body to skip checking. Without this lint an `unsafe fn` body is unchecked end to end, so a 600-line
|
|
# function hides which handful of lines are actually the unsafe ones — exactly the reviewer-hostile
|
|
# shape we are working down. (This is the Rust 2024 default; adopting it early also pays off the
|
|
# edition migration.)
|
|
#
|
|
# `deny`, not `warn`. `warn` was never actually a softer setting: CI runs `cargo clippy … -D
|
|
# warnings`, which promotes it to a hard error anyway — that is how adopting this lint turned main
|
|
# red on every platform for a day without the level in this file ever saying `deny`. A level that
|
|
# lies about its own severity is worse than a strict one, so this now states what CI already does,
|
|
# and the exemptions are written down per file instead of hiding in a 689-warning wall nobody reads.
|
|
#
|
|
# THE EXEMPTIONS. Fourteen GPU/FFI backend files carry `#![allow(unsafe_op_in_unsafe_fn)]` with a
|
|
# one-line reason each. They are not "not done yet" — they are where this lint stops paying:
|
|
# their bodies are ash/CUDA/AMF/libav calls almost line for line (measured: 64% of the sites are a
|
|
# single third-party FFI call, and of the 44 `unsafe fn`s in them only 4 have a body containing no
|
|
# unsafe operation at all). Narrowing them means one `unsafe {}` per line plus, since pf-encode also
|
|
# denies `clippy::undocumented_unsafe_blocks`, one hand-written SAFETY comment per line that could
|
|
# only ever restate "an ash call on a live device" — the precise noise that made `unsafe` stop
|
|
# meaning anything here before (see the header of `pf-win-display/src/win_display.rs`).
|
|
#
|
|
# Everything else in the workspace is at zero and enforced. Removing one of those allows, file by
|
|
# file, is real work with a real payoff; blanket-narrowing all fourteen is not. Prefer DELETING an
|
|
# `unsafe fn` marker over wrapping its body: keep the marker only where a caller can actually break
|
|
# something (a raw pointer, a borrowed HANDLE, a GPU object that must not be in flight).
|
|
[workspace.lints.rust]
|
|
unsafe_op_in_unsafe_fn = "deny"
|
|
|
|
[profile.release]
|
|
opt-level = 3
|
|
lto = "thin"
|
|
codegen-units = 1
|
|
# NOTE: deliberately NOT `panic = "abort"`. punktfunk-core ships as a cdylib/staticlib into
|
|
# third-party apps (Swift/Kotlin/C) and its C ABI catches panics at the boundary
|
|
# (`catch_unwind` → `PunktfunkStatus::Panic`). `panic = "abort"` would make that guard a
|
|
# no-op and let a stray panic abort the embedding application. Unwinding keeps the
|
|
# documented isolation guarantee real.
|
|
|
|
# The per-frame hot path must stay fast even in dev builds.
|
|
[profile.dev.package."*"]
|
|
opt-level = 2
|