diff --git a/src/backends/metal/present.rs b/src/backends/metal/present.rs index be9f266d..3c47749d 100644 --- a/src/backends/metal/present.rs +++ b/src/backends/metal/present.rs @@ -272,6 +272,10 @@ impl MetalConnector { self.can_present.set(false); if let Some(latched) = latched { self.has_damage.fetch_sub(latched.damage); + node.global + .connector + .damaged + .set(self.has_damage.is_not_zero()); } self.cursor_changed.set(false); Ok(()) diff --git a/src/compositor.rs b/src/compositor.rs index 1a93f071..fc6e7f9d 100644 --- a/src/compositor.rs +++ b/src/compositor.rs @@ -449,10 +449,19 @@ fn create_dummy_output(state: &Rc) { let connector = Rc::new(DummyOutput { id: state.connector_ids.next(), }) as Rc; + let connector_data = Rc::new(ConnectorData { + connector, + handler: Cell::new(None), + connected: Cell::new(true), + name: "Dummy".to_string(), + drm_dev: None, + async_event: Default::default(), + damaged: Cell::new(false), + }); let schedule = Rc::new(OutputSchedule::new( &state.ring, &state.eng, - &connector, + &connector_data, &persistent_state, )); let dummy_output = Rc::new(OutputNode { @@ -460,14 +469,7 @@ fn create_dummy_output(state: &Rc) { global: Rc::new(WlOutputGlobal::new( state.globals.name(), state, - &Rc::new(ConnectorData { - connector, - handler: Cell::new(None), - connected: Cell::new(true), - name: "Dummy".to_string(), - drm_dev: None, - async_event: Default::default(), - }), + &connector_data, Vec::new(), &backend::Mode { width: 0, diff --git a/src/damage.rs b/src/damage.rs index 9523415a..ec54877f 100644 --- a/src/damage.rs +++ b/src/damage.rs @@ -56,7 +56,7 @@ pub async fn visualize_damage(state: Rc) { fn damage_all(state: &State) { for connector in state.connectors.lock().values() { if connector.connected.get() { - connector.connector.damage(); + connector.damage(); } } } diff --git a/src/ifs/zwlr_screencopy_frame_v1.rs b/src/ifs/zwlr_screencopy_frame_v1.rs index a304c830..44afe8c5 100644 --- a/src/ifs/zwlr_screencopy_frame_v1.rs +++ b/src/ifs/zwlr_screencopy_frame_v1.rs @@ -117,7 +117,7 @@ impl ZwlrScreencopyFrameV1 { self.buffer.set(Some(buffer)); if !with_damage { if let Some(global) = self.output.get() { - global.connector.connector.damage(); + global.connector.damage(); } } self.with_damage.set(with_damage); diff --git a/src/output_schedule.rs b/src/output_schedule.rs index bb6e9da4..df83d6af 100644 --- a/src/output_schedule.rs +++ b/src/output_schedule.rs @@ -1,9 +1,10 @@ use { crate::{ async_engine::AsyncEngine, - backend::{Connector, HardwareCursor}, + backend::HardwareCursor, ifs::wl_output::PersistentOutputState, io_uring::{IoUring, IoUringError}, + state::ConnectorData, utils::{ asyncevent::AsyncEvent, cell_ext::CellExt, clonecell::CloneCell, errorfmt::ErrorFmt, numcell::NumCell, @@ -18,7 +19,7 @@ pub struct OutputSchedule { changed: AsyncEvent, run: Cell, - connector: Rc, + connector: Rc, hardware_cursor: CloneCell>>, persistent: Rc, @@ -42,7 +43,7 @@ impl OutputSchedule { pub fn new( ring: &Rc, eng: &Rc, - connector: &Rc, + connector: &Rc, persistent: &Rc, ) -> Self { let slf = Self { diff --git a/src/state.rs b/src/state.rs index e5669e04..aabc6b8b 100644 --- a/src/state.rs +++ b/src/state.rs @@ -300,6 +300,7 @@ pub struct ConnectorData { pub name: String, pub drm_dev: Option>, pub async_event: Rc, + pub damaged: Cell, } pub struct OutputData { @@ -321,6 +322,14 @@ pub struct DrmDevData { pub lease_global: Rc, } +impl ConnectorData { + pub fn damage(&self) { + if !self.damaged.replace(true) { + self.connector.damage(); + } + } +} + impl DrmDevData { pub fn make_render_device(&self) { log::info!( @@ -761,7 +770,7 @@ impl State { if cursor && output.schedule.defer_cursor_updates() { output.schedule.software_cursor_changed(); } else { - output.global.connector.connector.damage(); + output.global.connector.damage(); } } } diff --git a/src/tasks/connector.rs b/src/tasks/connector.rs index 5dbf2290..0a8d51ef 100644 --- a/src/tasks/connector.rs +++ b/src/tasks/connector.rs @@ -31,6 +31,7 @@ pub fn handle(state: &Rc, connector: &Rc) { name: connector.kernel_id().to_string(), drm_dev: drm_dev.clone(), async_event: Rc::new(AsyncEvent::default()), + damaged: Cell::new(false), }); if let Some(dev) = drm_dev { dev.connectors.set(id, data.clone()); @@ -137,7 +138,7 @@ impl ConnectorHandler { let schedule = Rc::new(OutputSchedule::new( &self.state.ring, &self.state.eng, - &self.data.connector, + &self.data, &desired_state, )); let _schedule = self.state.eng.spawn(schedule.clone().drive());