Add `feat-monado-timings` build feature

This commit is contained in:
Aleksander 2026-03-28 11:07:32 +01:00
parent 80277e0c12
commit 8ad31cfa28
4 changed files with 119 additions and 84 deletions

View File

@ -9,11 +9,11 @@ repository = "https://github.com/wlx-team/wayvr"
keywords = [ keywords = [
"linux", "linux",
"openvr", "openvr",
"openxr",
"x11",
"wayland",
"openvr-overlay", "openvr-overlay",
"openxr",
"openxr-overlay", "openxr-overlay",
"wayland",
"x11",
] ]
categories = ["games"] categories = ["games"]
@ -32,20 +32,19 @@ glam = { workspace = true, features = ["mint", "serde"] }
idmap = { workspace = true, features = ["serde"] } idmap = { workspace = true, features = ["serde"] }
idmap-derive.workspace = true idmap-derive.workspace = true
log.workspace = true log.workspace = true
rust-embed.workspace = true
regex.workspace = true regex.workspace = true
slotmap.workspace = true rust-embed.workspace = true
serde = { workspace = true, features = ["rc"] } serde = { workspace = true, features = ["rc"] }
serde_json.workspace = true serde_json.workspace = true
slotmap.workspace = true
strum.workspace = true strum.workspace = true
vulkano.workspace = true vulkano.workspace = true
vulkano-shaders.workspace = true vulkano-shaders.workspace = true
xdg.workspace = true xdg.workspace = true
ash = "^0.38.0" # must match vulkano ash = "^0.38.0" # must match vulkano
bytes = { version = "1.11.1" } bytes = { version = "1.11.1" }
chrono = { version = "0.4.42", features = [ "unstable-locales"]} chrono = { version = "0.4.42", features = ["unstable-locales"] }
pure-rust-locales = "0.8.2"
chrono-tz = "0.10.4" chrono-tz = "0.10.4"
config = "0.15.19" config = "0.15.19"
dbus = { version = "0.9.9" } dbus = { version = "0.9.9" }
@ -58,15 +57,16 @@ interprocess = { version = "2.2.3" }
json = { version = "0.12.4", optional = true } json = { version = "0.12.4", optional = true }
json5 = "1.3.0" json5 = "1.3.0"
libc = "0.2.178" libc = "0.2.178"
smol = { workspace = true }
libmonado = { git = "https://github.com/oo8dev/libmonado-rs.git", rev = "fc39940a64dea2df080a0d2c974c7d651006241f", optional = true } libmonado = { git = "https://github.com/oo8dev/libmonado-rs.git", rev = "fc39940a64dea2df080a0d2c974c7d651006241f", optional = true }
log-panics = { version = "2.1.0", features = ["with-backtrace"] } log-panics = { version = "2.1.0", features = ["with-backtrace"] }
mint = "0.5.9" mint = "0.5.9"
openxr = { version = "0.21.0", features = ["linked", "mint"], optional = true } openxr = { version = "0.21.0", features = ["linked", "mint"], optional = true }
ovr_overlay = { features = [ ovr_overlay = { git = "https://github.com/galister/ovr_overlay_oyasumi", rev = "e477bd2a9e04293ea68c1e7529ef2cb131f32acc", features = [
"ovr_input", "ovr_input",
"ovr_system", "ovr_system",
], git = "https://github.com/galister/ovr_overlay_oyasumi", rev = "e477bd2a9e04293ea68c1e7529ef2cb131f32acc", optional = true } ], optional = true }
prost = { version = "0.14.3", optional = true }
pure-rust-locales = "0.8.2"
rosc = { version = "0.11.4", optional = true } rosc = { version = "0.11.4", optional = true }
serde_json5 = "0.2.1" serde_json5 = "0.2.1"
serde_yaml = "0.9.34" serde_yaml = "0.9.34"
@ -75,33 +75,34 @@ smallvec = "1.15.1"
smithay = { version = "0.7.0", default-features = false, features = [ smithay = { version = "0.7.0", default-features = false, features = [
"backend_vulkan", "backend_vulkan",
"desktop", "desktop",
"xwayland",
"wayland_frontend", "wayland_frontend",
"xwayland",
] } ] }
smol = { workspace = true }
sysinfo = { version = "0.37" } sysinfo = { version = "0.37" }
thiserror = "2.0" thiserror = "2.0"
tracing-subscriber = { version = "0.3.22", features = ["env-filter"] }
tracing = "0.1.43" tracing = "0.1.43"
uuid = { version = "1.19.0", features = ["v4", "fast-rng"] } tracing-subscriber = { version = "0.3.22", features = ["env-filter"] }
uuid = { version = "1.19.0", features = ["fast-rng", "v4"] }
wayland-client = { workspace = true } wayland-client = { workspace = true }
winit = { version = "0.30.12", optional = true } winit = { version = "0.30.12", optional = true }
xcb = { version = "1.6.0", optional = true, features = [ xcb = { version = "1.6.0", features = [
"as-raw-xcb-connection", "as-raw-xcb-connection",
] } ], optional = true }
xkbcommon = { version = "0.8.0" } # 0.9.0 breaks keymap import on some distros xkbcommon = { version = "0.8.0" } # 0.9.0 breaks keymap import on some distros
prost = { version = "0.14.3", optional = true }
[build-dependencies] [build-dependencies]
regex.workspace = true regex.workspace = true
[features] [features]
default = ["openvr", "openxr", "osc", "x11", "wayland"] default = ["openvr", "openxr", "osc", "wayland", "x11"]
openvr = ["dep:ovr_overlay", "dep:json"] as-raw-xcb-connection = []
openxr = ["dep:openxr", "dep:libmonado", "dep:prost"] feat-monado-metrics = []
openvr = ["dep:json", "dep:ovr_overlay"]
openxr = ["dep:libmonado", "dep:openxr", "dep:prost"]
osc = ["dep:rosc"] osc = ["dep:rosc"]
x11 = ["dep:xcb", "wlx-capture/xshm", "xkbcommon/x11"]
wayland = ["pipewire", "wlx-capture/wlr", "xkbcommon/wayland"]
pipewire = ["wlx-capture/pipewire"] pipewire = ["wlx-capture/pipewire"]
uidev = ["dep:winit"] uidev = ["dep:winit"]
wayland = ["pipewire", "wlx-capture/wlr", "xkbcommon/wayland"]
x11 = ["dep:xcb", "wlx-capture/xshm", "xkbcommon/x11"]
xcb = ["dep:xcb"] xcb = ["dep:xcb"]
as-raw-xcb-connection = []

View File

@ -1,18 +1,26 @@
#[cfg(feature = "feat-monado-metrics")]
use crate::subsystem::monado_metrics::{self, metrics_fd::MonadoMetricsFd}; use crate::subsystem::monado_metrics::{self, metrics_fd::MonadoMetricsFd};
pub struct MonadoState { pub struct MonadoState {
pub ipc: libmonado::Monado, pub ipc: libmonado::Monado,
#[cfg(feature = "feat-monado-metrics")]
pub metrics: Option<MonadoMetricsFd>, pub metrics: Option<MonadoMetricsFd>,
} }
impl MonadoState { impl MonadoState {
pub fn new() -> anyhow::Result<Self> { pub fn new() -> anyhow::Result<Self> {
let ipc = libmonado::Monado::auto_connect().map_err(|s| anyhow::anyhow!("{s}"))?; let ipc = libmonado::Monado::auto_connect().map_err(|s| anyhow::anyhow!("{s}"))?;
let res = Self { ipc, metrics: None }; let res = Self {
ipc,
#[cfg(feature = "feat-monado-metrics")]
metrics: None,
};
Ok(res) Ok(res)
} }
pub fn update(&mut self) { pub fn update(&mut self) {
#[cfg(feature = "feat-monado-metrics")]
if let Some(metrics) = &mut self.metrics { if let Some(metrics) = &mut self.metrics {
metrics.update(); metrics.update();
@ -23,18 +31,26 @@ impl MonadoState {
} }
pub fn set_metrics_enabled(&mut self, enabled: bool) -> anyhow::Result<()> { pub fn set_metrics_enabled(&mut self, enabled: bool) -> anyhow::Result<()> {
if enabled { #[cfg(feature = "feat-monado-metrics")]
if self.metrics.is_none() { {
log::info!("Starting Monado metrics"); if enabled {
self.metrics = Some(monado_metrics::metrics_fd::MonadoMetricsFd::new( if self.metrics.is_none() {
&mut self.ipc, log::info!("Starting Monado metrics");
)?); self.metrics = Some(monado_metrics::metrics_fd::MonadoMetricsFd::new(
&mut self.ipc,
)?);
}
} else {
if self.metrics.is_some() {
log::info!("Stopping Monado metrics");
}
self.metrics = None;
} }
} else { }
if self.metrics.is_some() { #[cfg(not(feature = "feat-monado-metrics"))]
log::info!("Stopping Monado metrics"); {
} #[allow(path_statements)]
self.metrics = None; enabled;
} }
Ok(()) Ok(())

View File

@ -533,16 +533,25 @@ impl DashInterface<AppState> for DashInterfaceLive {
#[cfg(feature = "openxr")] #[cfg(feature = "openxr")]
fn monado_metrics_set_enabled(&mut self, app: &mut AppState, enabled: bool) -> bool { fn monado_metrics_set_enabled(&mut self, app: &mut AppState, enabled: bool) -> bool {
let Some(monado) = &mut app.monado_state else { #[cfg(feature = "feat-monado-metrics")]
return false; {
}; let Some(monado) = &mut app.monado_state else {
return false;
};
if let Err(e) = monado.set_metrics_enabled(enabled) { if let Err(e) = monado.set_metrics_enabled(enabled) {
log::error!("failed to enable metrics: {e:?}"); log::error!("failed to enable metrics: {e:?}");
return false; return false;
}
true
}
#[cfg(not(feature = "feat-monado-metrics"))]
#[allow(path_statements)]
{
app;
enabled;
false
} }
true
} }
#[cfg(feature = "openxr")] #[cfg(feature = "openxr")]
@ -551,48 +560,56 @@ impl DashInterface<AppState> for DashInterfaceLive {
&mut self, &mut self,
app: &mut AppState, app: &mut AppState,
) -> Vec<dash_interface::MonadoDumpSessionFrame> { ) -> Vec<dash_interface::MonadoDumpSessionFrame> {
let Some(monado) = &mut app.monado_state else { #[cfg(feature = "feat-monado-metrics")]
return Vec::new(); {
}; let Some(monado) = &mut app.monado_state else {
return Vec::new();
};
let Some(metrics) = &mut monado.metrics else {
return Vec::new(); // metrics not enabled or not available
};
let Some(metrics) = &mut monado.metrics else { metrics
return Vec::new(); // metrics not enabled or not available .dump_records()
}; .iter()
.filter_map(|record| {
metrics use crate::subsystem::monado_metrics::proto::record;
.dump_records() let record = record.record?;
.iter() match record {
.filter_map(|record| { record::Record::SessionFrame(sframe) => {
use crate::subsystem::monado_metrics::proto::record; // map it to our struct
let record = record.record?; Some(dash_interface::MonadoDumpSessionFrame {
match record { session_id: sframe.session_id,
record::Record::SessionFrame(sframe) => { frame_id: sframe.frame_id,
// map it to our struct predicted_frame_time_ns: sframe.predicted_frame_time_ns,
Some(dash_interface::MonadoDumpSessionFrame { predicted_wake_up_time_ns: sframe.predicted_wake_up_time_ns,
session_id: sframe.session_id, predicted_gpu_done_time_ns: sframe.predicted_gpu_done_time_ns,
frame_id: sframe.frame_id, predicted_display_time_ns: sframe.predicted_display_time_ns,
predicted_frame_time_ns: sframe.predicted_frame_time_ns, predicted_display_period_ns: sframe.predicted_display_period_ns,
predicted_wake_up_time_ns: sframe.predicted_wake_up_time_ns, display_time_ns: sframe.display_time_ns,
predicted_gpu_done_time_ns: sframe.predicted_gpu_done_time_ns, when_predicted_ns: sframe.when_predicted_ns,
predicted_display_time_ns: sframe.predicted_display_time_ns, when_wait_woke_ns: sframe.when_wait_woke_ns,
predicted_display_period_ns: sframe.predicted_display_period_ns, when_begin_ns: sframe.when_begin_ns,
display_time_ns: sframe.display_time_ns, when_delivered_ns: sframe.when_delivered_ns,
when_predicted_ns: sframe.when_predicted_ns, when_gpu_done_ns: sframe.when_gpu_done_ns,
when_wait_woke_ns: sframe.when_wait_woke_ns, discarded: sframe.discarded,
when_begin_ns: sframe.when_begin_ns, })
when_delivered_ns: sframe.when_delivered_ns, }
when_gpu_done_ns: sframe.when_gpu_done_ns, record::Record::Version(_) => None,
discarded: sframe.discarded, record::Record::Used(_) => None,
}) record::Record::SystemFrame(_) => None,
record::Record::SystemGpuInfo(_) => None,
record::Record::SystemPresentInfo(_) => None,
} }
record::Record::Version(_) => None, })
record::Record::Used(_) => None, .collect()
record::Record::SystemFrame(_) => None, }
record::Record::SystemGpuInfo(_) => None, #[cfg(not(feature = "feat-monado-metrics"))]
record::Record::SystemPresentInfo(_) => None, #[allow(path_statements)]
} {
}) app;
.collect() Vec::new()
}
} }
#[cfg(not(feature = "openxr"))] #[cfg(not(feature = "openxr"))]

View File

@ -7,4 +7,5 @@ pub mod notifications;
pub mod osc; pub mod osc;
#[cfg(feature = "openxr")] #[cfg(feature = "openxr")]
#[cfg(feature = "feat-monado-metrics")]
pub mod monado_metrics; pub mod monado_metrics;