1
0
Fork 0
forked from wry/wry
wry/src/state/connectors.rs

153 lines
4.8 KiB
Rust

use {
crate::{
backend::{
BackendConnectorState, BackendDrmDevice, Connector, ConnectorId, MonitorInfo,
transaction::BackendConnectorTransactionError,
},
ifs::{
head_management::HeadManagers,
wlr_output_manager::{
zwlr_output_head_v1::ZwlrOutputHeadV1,
zwlr_output_manager_v1::WlrOutputManagerId,
},
wp_drm_lease_connector_v1::WpDrmLeaseConnectorV1,
wp_drm_lease_device_v1::WpDrmLeaseDeviceV1Global,
},
rect::Rect,
tree::OutputNode,
utils::{
asyncevent::AsyncEvent, bindings::Bindings, copyhashmap::CopyHashMap,
},
},
jay_config::PciId,
std::{
cell::{Cell, RefCell},
rc::Rc,
},
};
use super::State;
pub struct ConnectorData {
pub id: ConnectorId,
pub connector: Rc<dyn Connector>,
pub handler: Cell<Option<crate::async_engine::SpawnedFuture<()>>>,
pub connected: Cell<bool>,
pub name: Rc<String>,
pub description: RefCell<String>,
pub drm_dev: Option<Rc<DrmDevData>>,
pub async_event: Rc<AsyncEvent>,
pub damaged: Cell<bool>,
pub damage: RefCell<Vec<Rect>>,
pub needs_vblank_emulation: Cell<bool>,
pub damage_intersect: Cell<Rect>,
pub state: RefCell<BackendConnectorState>,
pub head_managers: HeadManagers,
pub wlr_output_heads: CopyHashMap<WlrOutputManagerId, Rc<ZwlrOutputHeadV1>>,
}
pub struct OutputData {
pub connector: Rc<ConnectorData>,
pub monitor_info: Rc<MonitorInfo>,
pub node: Option<Rc<OutputNode>>,
pub lease_connectors: Rc<Bindings<WpDrmLeaseConnectorV1>>,
}
pub struct DrmDevData {
pub dev: Rc<dyn BackendDrmDevice>,
pub handler: Cell<Option<crate::async_engine::SpawnedFuture<()>>>,
pub connectors: CopyHashMap<ConnectorId, Rc<ConnectorData>>,
pub syspath: Option<String>,
pub devnode: Option<String>,
pub vendor: Option<String>,
pub model: Option<String>,
pub pci_id: Option<PciId>,
pub lease_global: Rc<WpDrmLeaseDeviceV1Global>,
}
impl ConnectorData {
pub fn damage(&self) {
if !self.damaged.replace(true) {
self.connector.damage();
}
}
pub fn modify_state(
&self,
state: &State,
f: impl FnOnce(&mut BackendConnectorState),
) -> Result<(), BackendConnectorTransactionError> {
let old = self.state.borrow().clone();
let mut s = old.clone();
f(&mut s);
if old == s {
return Ok(());
}
s.serial = state.backend_connector_state_serials.next();
let mut tran = self.connector.create_transaction()?;
tran.add(&self.connector, s.clone())?;
tran.prepare()?.apply()?.commit();
self.set_state(state, s);
Ok(())
}
pub fn set_state(&self, state: &State, s: BackendConnectorState) {
let old = self.state.borrow().clone();
if old.serial >= s.serial {
return;
}
*self.state.borrow_mut() = s.clone();
if old.enabled != s.enabled {
self.head_managers.handle_enabled_change(state, s.enabled);
}
if old.active != s.active {
self.head_managers.handle_active_change(s.active);
}
if old.non_desktop_override != s.non_desktop_override {
self.head_managers
.handle_non_desktop_override_changed(s.non_desktop_override);
}
if old.vrr != s.vrr {
self.head_managers.handle_vrr_change(s.vrr);
}
if old.tearing != s.tearing {
self.head_managers.handle_tearing_enabled_change(s.tearing);
}
if old.format != s.format {
self.head_managers.handle_format_change(s.format);
}
if (old.color_space, old.eotf) != (s.color_space, s.eotf) {
self.head_managers
.handle_colors_change(s.color_space, s.eotf);
}
if old.mode != s.mode {
self.head_managers.handle_mode_change(s.mode);
for head in self.wlr_output_heads.lock().values() {
head.handle_mode_change(s.mode);
}
}
if let Some(output) = state.outputs.get(&self.connector.id())
&& let Some(node) = &output.node
{
node.update_state(old, s);
}
}
}
impl DrmDevData {
pub fn make_render_device(&self) {
log::info!(
"Making {} the render device",
self.devnode.as_deref().unwrap_or("unknown"),
);
self.dev.clone().make_render_device();
}
pub fn set_direct_scanout_enabled(&self, _state: &State, enabled: bool) {
self.dev.set_direct_scanout_enabled(enabled);
}
pub fn set_flip_margin(&self, _state: &State, margin: u64) {
self.dev.set_flip_margin(margin);
}
}