backend: implement output transactions
This commit is contained in:
parent
f8d03c25a9
commit
7ab99bb840
25 changed files with 2712 additions and 1460 deletions
|
|
@ -1,6 +1,10 @@
|
|||
use {
|
||||
crate::{
|
||||
backend::{Connector, ConnectorEvent, ConnectorId, MonitorInfo},
|
||||
backend::{
|
||||
BackendConnectorState, BackendConnectorStateSerial, Connector, ConnectorEvent,
|
||||
ConnectorId, MonitorInfo,
|
||||
},
|
||||
format::XRGB8888,
|
||||
globals::GlobalName,
|
||||
ifs::{
|
||||
jay_tray_v1::JayTrayV1Global,
|
||||
|
|
@ -22,6 +26,18 @@ pub fn handle(state: &Rc<State>, connector: &Rc<dyn Connector>) {
|
|||
_ => panic!("connector's drm device does not exist"),
|
||||
};
|
||||
}
|
||||
let backend_state = BackendConnectorState {
|
||||
serial: BackendConnectorStateSerial::from_raw(0),
|
||||
enabled: true,
|
||||
active: false,
|
||||
mode: Default::default(),
|
||||
non_desktop_override: None,
|
||||
vrr: false,
|
||||
tearing: false,
|
||||
format: XRGB8888,
|
||||
color_space: Default::default(),
|
||||
transfer_function: Default::default(),
|
||||
};
|
||||
let id = connector.id();
|
||||
let data = Rc::new(ConnectorData {
|
||||
connector: connector.clone(),
|
||||
|
|
@ -34,6 +50,7 @@ pub fn handle(state: &Rc<State>, connector: &Rc<dyn Connector>) {
|
|||
damage: Default::default(),
|
||||
needs_vblank_emulation: Cell::new(false),
|
||||
damage_intersect: Default::default(),
|
||||
state: Cell::new(backend_state),
|
||||
});
|
||||
if let Some(dev) = drm_dev {
|
||||
dev.connectors.set(id, data.clone());
|
||||
|
|
@ -88,6 +105,10 @@ impl ConnectorHandler {
|
|||
async fn handle_connected(&self, info: MonitorInfo) {
|
||||
log::info!("Connector {} connected", self.data.connector.kernel_id());
|
||||
self.data.connected.set(true);
|
||||
let old_state = self.data.state.get();
|
||||
if old_state.serial < info.state.serial {
|
||||
self.data.state.set(info.state);
|
||||
}
|
||||
let name = self.state.globals.name();
|
||||
if info.non_desktop {
|
||||
self.handle_non_desktop_connected(info).await;
|
||||
|
|
@ -132,15 +153,12 @@ impl ConnectorHandler {
|
|||
&self.state,
|
||||
&self.data,
|
||||
info.modes.clone(),
|
||||
&info.initial_mode,
|
||||
info.width_mm,
|
||||
info.height_mm,
|
||||
&output_id,
|
||||
&desired_state,
|
||||
info.transfer_functions.clone(),
|
||||
info.transfer_function,
|
||||
info.color_spaces.clone(),
|
||||
info.color_space,
|
||||
info.primaries,
|
||||
info.luminance,
|
||||
));
|
||||
|
|
@ -268,18 +286,11 @@ impl ConnectorHandler {
|
|||
on.hardware_cursor.set(hc);
|
||||
self.state.refresh_hardware_cursors();
|
||||
}
|
||||
ConnectorEvent::ModeChanged(mode) => {
|
||||
on.update_mode(mode);
|
||||
}
|
||||
ConnectorEvent::VrrChanged(enabled) => {
|
||||
on.schedule.set_vrr_enabled(enabled);
|
||||
}
|
||||
ConnectorEvent::FormatsChanged(formats, format) => {
|
||||
ConnectorEvent::FormatsChanged(formats) => {
|
||||
on.global.formats.set(formats);
|
||||
on.global.format.set(format);
|
||||
}
|
||||
ConnectorEvent::ColorsChanged(bcs, btf) => {
|
||||
on.update_btf_and_bcs(btf, bcs);
|
||||
ConnectorEvent::State(state) => {
|
||||
on.update_state(state);
|
||||
}
|
||||
ev => unreachable!("received unexpected event {:?}", ev),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use {
|
||||
crate::{
|
||||
backend::Backend,
|
||||
backend::transaction::{BackendConnectorTransactionError, ConnectorTransaction},
|
||||
state::State,
|
||||
utils::{
|
||||
errorfmt::ErrorFmt,
|
||||
|
|
@ -12,7 +12,7 @@ use {
|
|||
uapi::c,
|
||||
};
|
||||
|
||||
pub async fn idle(state: Rc<State>, backend: Rc<dyn Backend>) {
|
||||
pub async fn idle(state: Rc<State>) {
|
||||
let timer = match TimerFd::new(c::CLOCK_MONOTONIC) {
|
||||
Ok(t) => t,
|
||||
Err(e) => {
|
||||
|
|
@ -24,7 +24,6 @@ pub async fn idle(state: Rc<State>, backend: Rc<dyn Backend>) {
|
|||
state.idle.timeout_changed.set(true);
|
||||
let mut idle = Idle {
|
||||
state,
|
||||
backend,
|
||||
timer,
|
||||
idle: false,
|
||||
dead: false,
|
||||
|
|
@ -36,7 +35,6 @@ pub async fn idle(state: Rc<State>, backend: Rc<dyn Backend>) {
|
|||
|
||||
struct Idle {
|
||||
state: Rc<State>,
|
||||
backend: Rc<dyn Backend>,
|
||||
timer: TimerFd,
|
||||
idle: bool,
|
||||
dead: bool,
|
||||
|
|
@ -71,7 +69,7 @@ impl Idle {
|
|||
if let Some(config) = self.state.config.get() {
|
||||
config.idle();
|
||||
}
|
||||
self.backend.set_idle(true);
|
||||
self.set_idle(true);
|
||||
self.idle = true;
|
||||
}
|
||||
} else if since >= timeout {
|
||||
|
|
@ -110,7 +108,7 @@ impl Idle {
|
|||
self.last_input = now();
|
||||
self.set_in_grace_period(false);
|
||||
if self.idle {
|
||||
self.backend.set_idle(false);
|
||||
self.set_idle(false);
|
||||
self.idle = false;
|
||||
self.program_timer();
|
||||
}
|
||||
|
|
@ -127,6 +125,27 @@ impl Idle {
|
|||
self.dead = true;
|
||||
}
|
||||
}
|
||||
|
||||
fn set_idle(&self, idle: bool) {
|
||||
if let Err(e) = self.try_set_idle(idle) {
|
||||
log::error!("Could not change idle status of backend: {}", ErrorFmt(e))
|
||||
}
|
||||
if let Some(lock) = self.state.lock.lock.get() {
|
||||
lock.check_locked();
|
||||
}
|
||||
}
|
||||
|
||||
fn try_set_idle(&self, idle: bool) -> Result<(), BackendConnectorTransactionError> {
|
||||
let mut tran = ConnectorTransaction::default();
|
||||
for connector in self.state.connectors.lock().values() {
|
||||
let mut state = connector.state.get();
|
||||
state.active = !idle;
|
||||
tran.add(&connector.connector, state)?;
|
||||
}
|
||||
tran.prepare()?.apply()?.commit();
|
||||
self.state.set_backend_idle(idle);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn now() -> c::timespec {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue