ROGCC: Better handle the use of GPU MUX without supergfxd

This commit is contained in:
Luke D. Jones
2022-12-10 17:06:51 +13:00
parent b1ee449b97
commit dbfd73da5e
10 changed files with 209 additions and 83 deletions

View File

@@ -1,5 +1,5 @@
use eframe::{IconData, NativeOptions};
use log::{error, info, LevelFilter};
use log::{error, info};
use rog_aura::layouts::KeyLayout;
use rog_control_center::tray::init_tray;
use rog_control_center::update_and_notify::EnabledNotifications;
@@ -29,9 +29,9 @@ fn main() -> Result<()> {
print_versions();
let mut logger = env_logger::Builder::new();
logger
.parse_default_env()
.target(env_logger::Target::Stdout)
.format(|buf, record| writeln!(buf, "{}: {}", record.level(), record.args()))
.filter(None, LevelFilter::Info)
.init();
// start tokio

View File

@@ -4,6 +4,7 @@
use std::{
io::Write,
sync::{
atomic::{AtomicBool, Ordering},
mpsc::{channel, Receiver},
Arc, Mutex,
},
@@ -21,7 +22,7 @@ use supergfxctl::{
zbus_proxy::DaemonProxyBlocking as GfxProxyBlocking,
};
use log::{debug, error, info, trace};
use log::{debug, error, info, trace, warn};
const TRAY_APP_ICON: &str = "rog-control-center";
const TRAY_LABEL: &str = "ROG Control Center";
@@ -241,7 +242,10 @@ impl ROGTray {
}
fn menu_add_gpu(&mut self, supported: &SupportedFunctions, current_mode: GfxMode) {
let set_mux_off = Arc::new(AtomicBool::new(false));
let gfx_dbus = self.gfx_proxy.clone();
let set_mux_off1 = set_mux_off.clone();
let mut gpu_menu = RadioGroup::new("Integrated", move |_| {
let mode = gfx_dbus
.mode()
@@ -259,9 +263,11 @@ impl ROGTray {
})
.ok();
}
set_mux_off1.store(true, Ordering::Relaxed);
});
let gfx_dbus = self.gfx_proxy.clone();
let set_mux_off1 = set_mux_off.clone();
gpu_menu.add("Hybrid", move |_| {
let mode = gfx_dbus
.mode()
@@ -279,7 +285,31 @@ impl ROGTray {
})
.ok();
}
set_mux_off1.store(true, Ordering::Relaxed);
});
if supported.rog_bios_ctrl.egpu_enable {
let set_mux_off1 = set_mux_off.clone();
let gfx_dbus = self.gfx_proxy.clone();
gpu_menu.add("eGPU", move |_| {
let mode = gfx_dbus
.mode()
.map_err(|e| {
error!("ROGTray: mode: {e}");
e
})
.unwrap_or(GfxMode::None);
if mode != GfxMode::Egpu {
gfx_dbus
.set_mode(&GfxMode::Egpu)
.map_err(|e| {
error!("ROGTray: set_mode: {e}");
e
})
.ok();
}
set_mux_off1.store(true, Ordering::Relaxed);
});
}
if supported.rog_bios_ctrl.gpu_mux {
let gfx_dbus = self.bios_proxy.clone();
gpu_menu.add("Ultimate (Reboot required)", move |_| {
@@ -300,27 +330,17 @@ impl ROGTray {
.ok();
}
});
}
if supported.rog_bios_ctrl.egpu_enable {
let gfx_dbus = self.gfx_proxy.clone();
gpu_menu.add("eGPU", move |_| {
let mode = gfx_dbus
.mode()
if set_mux_off.load(Ordering::Relaxed) {
warn!("Selected non-dgpu mode, must set MUX to optimus");
self.bios_proxy
.set_gpu_mux_mode(GpuMode::Optimus)
.map_err(|e| {
error!("ROGTray: mode: {e}");
error!("ROGTray: set_mode: {e}");
e
})
.unwrap_or(GfxMode::None);
if mode != GfxMode::Egpu {
gfx_dbus
.set_mode(&GfxMode::Egpu)
.map_err(|e| {
error!("ROGTray: set_mode: {e}");
e
})
.ok();
}
});
.ok();
}
}
let active = match current_mode {
@@ -336,6 +356,61 @@ impl ROGTray {
debug!("ROGTray: appended gpu menu");
}
fn menu_add_mux(&mut self, current_mode: GfxMode) {
let gfx_dbus = self.bios_proxy.clone();
let mut reboot_required = false;
if let Ok(mode) = gfx_dbus.gpu_mux_mode() {
let mode = match mode {
GpuMode::Discrete => GfxMode::AsusMuxDiscreet,
_ => GfxMode::Hybrid,
};
reboot_required = mode != current_mode;
}
let mut gpu_menu = RadioGroup::new("Optimus", move |_| {
gfx_dbus
.set_gpu_mux_mode(GpuMode::Optimus)
.map_err(|e| {
error!("ROGTray: set_mode: {e}");
e
})
.ok();
debug!("Setting GPU mode: {}", GpuMode::Optimus);
});
let gfx_dbus = self.bios_proxy.clone();
gpu_menu.add("Ultimate", move |_| {
gfx_dbus
.set_gpu_mux_mode(GpuMode::Discrete)
.map_err(|e| {
error!("ROGTray: set_mode: {e}");
e
})
.ok();
debug!("Setting GPU mode: {}", GpuMode::Discrete);
});
let active = match current_mode {
GfxMode::AsusMuxDiscreet => "Ultimate".to_owned(),
GfxMode::Hybrid => "Optimus".to_owned(),
_ => current_mode.to_string(),
};
debug!("Current active GPU mode: {}", active);
let reboot_required = if reboot_required {
"(Reboot required)"
} else {
""
};
self.add_radio_sub_menu(
&format!("GPU Mode: {active} {reboot_required}"),
active.as_str(),
&gpu_menu,
);
debug!("ROGTray: appended gpu menu");
}
fn menu_clear(&mut self) {
self.menu = gtk::Menu::new();
debug!("ROGTray: cleared self");
@@ -362,6 +437,8 @@ impl ROGTray {
self.menu_add_panel_od(supported, panel_od);
if has_supergfx {
self.menu_add_gpu(supported, current_gfx_mode);
} else if supported.rog_bios_ctrl.gpu_mux {
self.menu_add_mux(current_gfx_mode);
}
self.menu_update();
}
@@ -412,10 +489,19 @@ pub fn init_tray(
loop {
if let Ok(mut lock) = states.lock() {
if lock.tray_should_update {
// Supergfx ends up adding some complexity to handle if it isn't available
let current_gpu_mode = if lock.gfx_state.has_supergfx {
lock.gfx_state.mode
} else {
match lock.bios.dedicated_gfx {
GpuMode::Discrete => GfxMode::AsusMuxDiscreet,
_ => GfxMode::Hybrid,
}
};
tray.rebuild_and_update(
&supported,
has_supergfx,
lock.gfx_state.mode,
current_gpu_mode,
lock.power_state.charge_limit,
lock.bios.panel_overdrive,
);

View File

@@ -185,18 +185,6 @@ pub fn start_notifications(
do_notification
);
recv_notif!(
RogBiosProxy,
receive_notify_gpu_mux_mode,
last_notification,
enabled_notifications,
page_states,
(bios.dedicated_gfx),
(mode),
"Reboot required. BIOS GPU MUX mode set to",
do_mux_notification
);
// Charge notif
recv_notif!(
PowerProxy,
@@ -277,6 +265,43 @@ pub fn start_notifications(
};
});
let page_states1 = page_states.clone();
let last_notification1 = last_notification.clone();
tokio::spawn(async move {
let conn = zbus::Connection::system()
.await
.map_err(|e| {
error!("zbus signal: receive_notify_gpu_mux_mode: {e}");
e
})
.unwrap();
let proxy = RogBiosProxy::new(&conn)
.await
.map_err(|e| {
error!("zbus signal: receive_notify_gpu_mux_mode: {e}");
e
})
.unwrap();
if let Ok(mut p) = proxy.receive_notify_gpu_mux_mode().await {
info!("Started zbus signal thread: receive_power_states");
while let Some(e) = p.next().await {
if let Ok(out) = e.args() {
if let Ok(mut lock) = page_states1.lock() {
lock.bios.dedicated_gfx = out.mode;
lock.set_notified();
}
if let Ok(ref mut lock) = last_notification1.lock() {
if let Some(notif) = lock.take() {
notif.close();
}
}
do_mux_notification("Reboot required. BIOS GPU MUX mode set to", &out.mode)
.ok();
}
}
};
});
if let Ok(lock) = page_states.try_lock() {
use supergfxctl::pci_device::Device;
let dev = Device::find().unwrap_or_default();
@@ -456,10 +481,24 @@ where
}
/// Actual `GpuMode` unused as data is never correct until switched by reboot
fn do_mux_notification(message: &str, _: &GpuMode) -> Result<NotificationHandle> {
let mut notif = base_notification(message, &"");
fn do_mux_notification(message: &str, m: &GpuMode) -> Result<()> {
let mut notif = base_notification(message, &m.to_string());
notif.action("gnome-session-quit", "Reboot");
notif.urgency(Urgency::Critical);
notif.icon("system-reboot-symbolic");
notif.hint(Hint::Transient(true));
Ok(notif.show()?)
let handle = notif.show()?;
std::thread::spawn(|| {
handle.wait_for_action(|id| {
if id == "gnome-session-quit" {
let mut cmd = Command::new("gnome-session-quit");
cmd.arg("--reboot");
cmd.spawn().ok();
} else if id == "__closed" {
// TODO: cancel the switching
}
})
});
Ok(())
}

View File

@@ -93,6 +93,13 @@ pub fn rog_bios_group(supported: &SupportedFunctions, states: &mut SystemState,
if supported.rog_bios_ctrl.gpu_mux {
let mut changed = false;
let mut dedicated_gfx = states.bios.dedicated_gfx;
let mut reboot_required = false;
if let Ok(mode) = states.asus_dbus.proxies().rog_bios().gpu_mux_mode() {
reboot_required = mode != states.bios.dedicated_gfx;
}
ui.group(|ui| {
ui.vertical(|ui| {
ui.horizontal_wrapped(|ui| ui.label("GPU MUX mode"));
@@ -100,19 +107,23 @@ pub fn rog_bios_group(supported: &SupportedFunctions, states: &mut SystemState,
ui.horizontal_wrapped(|ui| {
changed = ui
.selectable_value(
&mut states.bios.dedicated_gfx,
&mut dedicated_gfx,
GpuMode::Discrete,
"Dedicated (Ultimate)",
)
.clicked()
|| ui
.selectable_value(
&mut states.bios.dedicated_gfx,
&mut dedicated_gfx,
GpuMode::Optimus,
"Optimus (Hybrid)",
)
.clicked();
});
if reboot_required {
ui.horizontal_wrapped(|ui| ui.heading("REBOOT REQUIRED"));
}
});
});
@@ -121,7 +132,7 @@ pub fn rog_bios_group(supported: &SupportedFunctions, states: &mut SystemState,
.asus_dbus
.proxies()
.rog_bios()
.set_gpu_mux_mode(states.bios.dedicated_gfx)
.set_gpu_mux_mode(dedicated_gfx)
.map_err(|err| {
states.error = Some(err.to_string());
})