control-center: add GPUs pane
This commit is contained in:
parent
d328655f8b
commit
db06d719dd
7 changed files with 170 additions and 11 deletions
|
|
@ -588,7 +588,6 @@ pub trait BackendDrmDevice {
|
|||
fn set_flip_margin(&self, margin: u64) {
|
||||
let _ = margin;
|
||||
}
|
||||
#[expect(dead_code)]
|
||||
fn flip_margin(&self) -> Option<u64> {
|
||||
None
|
||||
}
|
||||
|
|
|
|||
|
|
@ -951,8 +951,10 @@ impl ConfigProxyHandler {
|
|||
}
|
||||
|
||||
fn handle_set_flip_margin(&self, device: DrmDevice, margin: Duration) -> Result<(), CphError> {
|
||||
self.get_drm_device(device)?
|
||||
.set_flip_margin(margin.as_nanos().try_into().unwrap_or(u64::MAX));
|
||||
self.get_drm_device(device)?.set_flip_margin(
|
||||
&self.state,
|
||||
margin.as_nanos().try_into().unwrap_or(u64::MAX),
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
@ -987,7 +989,7 @@ impl ConfigProxyHandler {
|
|||
match device {
|
||||
Some(dev) => self
|
||||
.get_drm_device(dev)?
|
||||
.set_direct_scanout_enabled(enabled),
|
||||
.set_direct_scanout_enabled(&self.state, enabled),
|
||||
_ => self.state.direct_scanout_enabled.set(enabled),
|
||||
}
|
||||
Ok(())
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@ use {
|
|||
crate::{
|
||||
control_center::{
|
||||
cc_color_management::ColorManagementPane, cc_compositor::CompositorPane,
|
||||
cc_idle::IdlePane, cc_outputs::OutputsPane, cc_xwayland::XwaylandPane,
|
||||
cc_gpus::GpusPane, cc_idle::IdlePane, cc_outputs::OutputsPane,
|
||||
cc_xwayland::XwaylandPane,
|
||||
},
|
||||
egui_adapter::egui_platform::{
|
||||
EggError, EggWindow, EggWindowOwner,
|
||||
|
|
@ -35,6 +36,7 @@ use {
|
|||
|
||||
mod cc_color_management;
|
||||
mod cc_compositor;
|
||||
mod cc_gpus;
|
||||
mod cc_idle;
|
||||
mod cc_outputs;
|
||||
mod cc_sidebar;
|
||||
|
|
@ -76,6 +78,7 @@ bitflags! {
|
|||
CCI_COLOR_MANAGEMENT,
|
||||
CCI_XWAYLAND,
|
||||
CCI_OUTPUTS,
|
||||
CCI_GPUS,
|
||||
}
|
||||
|
||||
pub struct ControlCenter {
|
||||
|
|
@ -121,6 +124,7 @@ enum PaneType {
|
|||
ColorManagement(ColorManagementPane),
|
||||
Xwayland(XwaylandPane),
|
||||
Outputs(Box<OutputsPane>),
|
||||
GPUs(GpusPane),
|
||||
}
|
||||
|
||||
struct CcBehavior<'a> {
|
||||
|
|
@ -144,6 +148,7 @@ impl Pane {
|
|||
PaneType::ColorManagement(v) => v.title(res),
|
||||
PaneType::Xwayland(v) => v.title(res),
|
||||
PaneType::Outputs(v) => v.title(res),
|
||||
PaneType::GPUs(v) => v.title(res),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -154,6 +159,7 @@ impl Pane {
|
|||
PaneType::ColorManagement(p) => p.show(ui),
|
||||
PaneType::Xwayland(p) => p.show(behavior, ui),
|
||||
PaneType::Outputs(p) => p.show(&mut self.ps, ui),
|
||||
PaneType::GPUs(p) => p.show(ui),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -166,6 +172,7 @@ impl PaneType {
|
|||
PaneType::ColorManagement(_) => CCI_COLOR_MANAGEMENT,
|
||||
PaneType::Xwayland(_) => CCI_XWAYLAND,
|
||||
PaneType::Outputs(_) => CCI_OUTPUTS,
|
||||
PaneType::GPUs(_) => CCI_GPUS,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
146
src/control_center/cc_gpus.rs
Normal file
146
src/control_center/cc_gpus.rs
Normal file
|
|
@ -0,0 +1,146 @@
|
|||
use {
|
||||
crate::{
|
||||
control_center::{
|
||||
ControlCenterInner, GridExt, bool, combo_box, grid, grid_label, label, row,
|
||||
},
|
||||
egui_adapter::egui_platform::icons::{ICON_ADD, ICON_REMOVE},
|
||||
state::{DrmDevData, State},
|
||||
},
|
||||
egui::{Checkbox, CollapsingHeader, DragValue, TextFormat, Ui, Widget, text::LayoutJob},
|
||||
std::rc::Rc,
|
||||
};
|
||||
|
||||
pub struct GpusPane {
|
||||
state: Rc<State>,
|
||||
}
|
||||
|
||||
impl ControlCenterInner {
|
||||
pub fn create_gpus_pane(self: &Rc<Self>) -> GpusPane {
|
||||
GpusPane {
|
||||
state: self.state.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl GpusPane {
|
||||
pub fn title(&self, res: &mut String) {
|
||||
res.push_str("GPUs");
|
||||
}
|
||||
|
||||
pub fn show(&mut self, ui: &mut Ui) {
|
||||
let devs = self.state.drm_devs.lock();
|
||||
let mut devs: Vec<_> = devs.iter().collect();
|
||||
devs.sort_by_key(|d| d.0);
|
||||
for dev in devs {
|
||||
self.show_dev(ui, dev.1);
|
||||
}
|
||||
}
|
||||
|
||||
fn show_dev(&self, ui: &mut Ui, dev: &DrmDevData) {
|
||||
let title_buf;
|
||||
let title = match dev.devnode.as_deref() {
|
||||
Some(t) => t,
|
||||
_ => {
|
||||
let dev_t = dev.dev.dev_t();
|
||||
title_buf = format!("{}:{}", uapi::major(dev_t), uapi::minor(dev_t));
|
||||
&title_buf
|
||||
}
|
||||
};
|
||||
let mut layout_job = LayoutJob::default();
|
||||
layout_job.append(
|
||||
title,
|
||||
0.0,
|
||||
TextFormat {
|
||||
color: ui.style().visuals.widgets.active.text_color(),
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
if let Some(model) = &dev.model {
|
||||
layout_job.append(
|
||||
model,
|
||||
10.0,
|
||||
TextFormat {
|
||||
color: ui.style().visuals.widgets.inactive.text_color(),
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
}
|
||||
ui.collapsing(layout_job, |ui| {
|
||||
grid(ui, ("settings", dev.dev.id()), |ui| {
|
||||
macro_rules! string {
|
||||
($field:ident, $name:expr) => {
|
||||
if let Some(v) = &dev.$field {
|
||||
label(ui, $name, v);
|
||||
}
|
||||
};
|
||||
}
|
||||
string!(vendor, "Vendor");
|
||||
string!(model, "Model");
|
||||
string!(devnode, "Devnode");
|
||||
string!(syspath, "Syspath");
|
||||
if let Some(v) = dev.pci_id {
|
||||
label(ui, "PCI ID", format!("{:x}:{:x}", v.vendor, v.model));
|
||||
}
|
||||
{
|
||||
let v = dev.dev.dev_t();
|
||||
label(ui, "Dev", format!("{}:{}", uapi::major(v), uapi::minor(v)));
|
||||
}
|
||||
combo_box(ui, "API", dev.dev.gtx_api(), |v| dev.dev.set_gfx_api(v));
|
||||
row(ui, "Primary Device", |ui| {
|
||||
let mut v = dev.dev.is_render_device();
|
||||
let old = v;
|
||||
ui.add_enabled(!v, Checkbox::without_text(&mut v));
|
||||
if v != old {
|
||||
dev.dev.make_render_device();
|
||||
}
|
||||
});
|
||||
bool(
|
||||
ui,
|
||||
"Direct Scanout",
|
||||
dev.dev.direct_scanout_enabled(),
|
||||
|v| dev.set_direct_scanout_enabled(&self.state, v),
|
||||
);
|
||||
if let Some(mut v) = dev.dev.flip_margin() {
|
||||
let ui = &mut *ui.row();
|
||||
grid_label(ui, "Flip Margin");
|
||||
let old = v;
|
||||
let denom = 1_000_000.0;
|
||||
ui.horizontal(|ui| {
|
||||
let mut s = v as f64 / denom;
|
||||
let res = DragValue::new(&mut s)
|
||||
.range(0.0..=50.0)
|
||||
.speed(0.1)
|
||||
.fixed_decimals(1)
|
||||
.ui(ui);
|
||||
if res.changed() {
|
||||
v = (s * denom) as u64;
|
||||
}
|
||||
if ui.button(ICON_REMOVE).clicked() {
|
||||
v = v.saturating_sub(100_000);
|
||||
}
|
||||
if ui.button(ICON_ADD).clicked() {
|
||||
v += 100_000;
|
||||
}
|
||||
});
|
||||
if old != v {
|
||||
dev.set_flip_margin(&self.state, v);
|
||||
}
|
||||
}
|
||||
});
|
||||
CollapsingHeader::new("Connectors")
|
||||
.default_open(true)
|
||||
.show(ui, |ui| {
|
||||
let mut cs: Vec<_> = dev
|
||||
.connectors
|
||||
.lock()
|
||||
.values()
|
||||
.map(|v| v.connector.kernel_id().to_string())
|
||||
.collect::<Vec<_>>();
|
||||
cs.sort();
|
||||
for c in cs {
|
||||
ui.label(c);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -13,6 +13,7 @@ enum PaneName {
|
|||
ColorManagement,
|
||||
Xwayland,
|
||||
Outputs,
|
||||
GPUs,
|
||||
}
|
||||
|
||||
impl PaneName {
|
||||
|
|
@ -23,6 +24,7 @@ impl PaneName {
|
|||
PaneName::ColorManagement => "Color Management",
|
||||
PaneName::Xwayland => "Xwayland",
|
||||
PaneName::Outputs => "Outputs",
|
||||
PaneName::GPUs => "GPUs",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -60,6 +62,7 @@ impl ControlCenterInner {
|
|||
PaneName::Outputs => {
|
||||
PaneType::Outputs(Box::new(self.create_outputs_pane()))
|
||||
}
|
||||
PaneName::GPUs => PaneType::GPUs(self.create_gpus_pane()),
|
||||
};
|
||||
self.open(tree, ty);
|
||||
ui.ctx().request_repaint();
|
||||
|
|
|
|||
|
|
@ -350,7 +350,7 @@ impl JayRandrRequestHandler for JayRandr {
|
|||
let Some(dev) = self.get_device(req.dev) else {
|
||||
return Ok(());
|
||||
};
|
||||
dev.set_direct_scanout_enabled(req.enabled != 0);
|
||||
dev.set_direct_scanout_enabled(&self.state, req.enabled != 0);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
@ -493,7 +493,7 @@ impl JayRandrRequestHandler for JayRandr {
|
|||
let Some(dev) = self.get_device(req.dev) else {
|
||||
return Ok(());
|
||||
};
|
||||
dev.set_flip_margin(req.margin_ns);
|
||||
dev.set_flip_margin(&self.state, req.margin_ns);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
|||
10
src/state.rs
10
src/state.rs
|
|
@ -17,7 +17,7 @@ use {
|
|||
compositor::{LIBEI_SOCKET, LogLevel},
|
||||
config::ConfigProxy,
|
||||
control_center::{
|
||||
CCI_COLOR_MANAGEMENT, CCI_COMPOSITOR, CCI_IDLE, CCI_OUTPUTS, CCI_XWAYLAND,
|
||||
CCI_COLOR_MANAGEMENT, CCI_COMPOSITOR, CCI_GPUS, CCI_IDLE, CCI_OUTPUTS, CCI_XWAYLAND,
|
||||
ControlCenters,
|
||||
},
|
||||
copy_device::CopyDeviceRegistry,
|
||||
|
|
@ -549,12 +549,14 @@ impl DrmDevData {
|
|||
self.dev.clone().make_render_device();
|
||||
}
|
||||
|
||||
pub fn set_direct_scanout_enabled(&self, enabled: bool) {
|
||||
pub fn set_direct_scanout_enabled(&self, state: &State, enabled: bool) {
|
||||
self.dev.set_direct_scanout_enabled(enabled);
|
||||
state.trigger_cci(CCI_GPUS);
|
||||
}
|
||||
|
||||
pub fn set_flip_margin(&self, margin: u64) {
|
||||
pub fn set_flip_margin(&self, state: &State, margin: u64) {
|
||||
self.dev.set_flip_margin(margin);
|
||||
state.trigger_cci(CCI_GPUS);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -778,7 +780,7 @@ impl State {
|
|||
}
|
||||
|
||||
self.expose_new_singletons();
|
||||
self.trigger_cci(CCI_COLOR_MANAGEMENT);
|
||||
self.trigger_cci(CCI_COLOR_MANAGEMENT | CCI_GPUS);
|
||||
}
|
||||
|
||||
fn reload_cursors(&self) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue