From a7f8a26df74ed577f0045ffaebca837c245c8e69 Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Mon, 14 Jul 2025 15:00:56 +0200 Subject: [PATCH] head-management: add jay-tearing-mode-info-v1 extension --- src/compositor.rs | 1 + src/config/handler.rs | 3 +- src/ifs/head_management.rs | 20 +++++++- .../head_management/head_management_macros.rs | 1 + src/ifs/head_management/jay_head_ext.rs | 1 + .../jay_head_ext_jay_tearing_mode_info_v1.rs | 51 +++++++++++++++++++ src/ifs/jay_randr.rs | 3 +- src/tasks/connector.rs | 1 + src/tree/output.rs | 23 ++++++--- .../jay_head_ext_jay_tearing_mode_info_v1.txt | 7 +++ ...d_manager_ext_jay_tearing_mode_info_v1.txt | 7 +++ 11 files changed, 107 insertions(+), 11 deletions(-) create mode 100644 src/ifs/head_management/jay_head_ext/jay_head_ext_jay_tearing_mode_info_v1.rs create mode 100644 wire/jay_head_ext_jay_tearing_mode_info_v1.txt create mode 100644 wire/jay_head_manager_ext_jay_tearing_mode_info_v1.txt diff --git a/src/compositor.rs b/src/compositor.rs index 119496eb..382bc46e 100644 --- a/src/compositor.rs +++ b/src/compositor.rs @@ -657,6 +657,7 @@ fn create_dummy_output(state: &Rc) { vrr_mode: VrrMode::Never.to_config(), tearing_enabled: backend_state.tearing, tearing_active: false, + tearing_mode: TearingMode::Never.to_config(), format: XRGB8888, color_space: backend_state.color_space, transfer_function: backend_state.transfer_function, diff --git a/src/config/handler.rs b/src/config/handler.rs index 89186d4e..b5bcc141 100644 --- a/src/config/handler.rs +++ b/src/config/handler.rs @@ -1413,8 +1413,7 @@ impl ConfigProxyHandler { match connector { Some(c) => { let connector = self.get_output_node(c)?; - connector.global.persistent.tearing_mode.set(mode); - connector.update_presentation_type(); + connector.set_tearing_mode(mode); } _ => self.state.default_tearing_mode.set(mode), } diff --git a/src/ifs/head_management.rs b/src/ifs/head_management.rs index ec270be9..006093fe 100644 --- a/src/ifs/head_management.rs +++ b/src/ifs/head_management.rs @@ -17,7 +17,7 @@ use { utils::{copyhashmap::CopyHashMap, hash_map_ext::HashMapExt, rc_eq::RcEq}, wire::JayHeadManagerSessionV1Id, }, - jay_config::video::{Transform, VrrMode}, + jay_config::video::{TearingMode, Transform, VrrMode}, std::{ cell::{Cell, RefCell}, rc::Rc, @@ -87,6 +87,7 @@ pub struct HeadState { pub vrr_mode: VrrMode, pub tearing_enabled: bool, pub tearing_active: bool, + pub tearing_mode: TearingMode, pub format: &'static Format, pub color_space: BackendColorSpace, pub transfer_function: BackendTransferFunction, @@ -231,6 +232,7 @@ impl HeadManagers { state.mode = n.global.mode.get(); state.transform = n.global.persistent.transform.get(); state.vrr_mode = n.global.persistent.vrr_mode.get().to_config(); + state.tearing_mode = n.global.persistent.tearing_mode.get().to_config(); } for head in self.managers.lock().values() { skip_in_transaction!(head); @@ -270,6 +272,10 @@ impl HeadManagers { ext.send_mode(state); head.session.schedule_done(); } + if let Some(ext) = &head.ext.jay_tearing_mode_info_v1 { + ext.send_mode(state); + head.session.schedule_done(); + } } } @@ -433,6 +439,18 @@ impl HeadManagers { } } + pub fn handle_tearing_mode_change(&self, tearing_mode: TearingMode) { + let state = &mut *self.state.borrow_mut(); + state.tearing_mode = tearing_mode; + for head in self.managers.lock().values() { + skip_in_transaction!(head); + if let Some(ext) = &head.ext.jay_tearing_mode_info_v1 { + ext.send_mode(state); + head.session.schedule_done(); + } + } + } + pub fn handle_format_change(&self, format: &'static Format) { let state = &mut *self.state.borrow_mut(); state.format = format; diff --git a/src/ifs/head_management/head_management_macros.rs b/src/ifs/head_management/head_management_macros.rs index 125f3c2f..67ae0447 100644 --- a/src/ifs/head_management/head_management_macros.rs +++ b/src/ifs/head_management/head_management_macros.rs @@ -405,4 +405,5 @@ declare_extensions! { drm_color_space_info_v1: DrmColorSpaceInfoV1, non_desktop_override_v1: NonDesktopOverrideV1, jay_vrr_mode_info_v1: JayVrrModeInfoV1, + jay_tearing_mode_info_v1: JayTearingModeInfoV1, } diff --git a/src/ifs/head_management/jay_head_ext.rs b/src/ifs/head_management/jay_head_ext.rs index b9445087..a217dbf9 100644 --- a/src/ifs/head_management/jay_head_ext.rs +++ b/src/ifs/head_management/jay_head_ext.rs @@ -7,6 +7,7 @@ pub(super) mod jay_head_ext_connector_info_v1; pub(super) mod jay_head_ext_core_info_v1; pub(super) mod jay_head_ext_drm_color_space_info_v1; pub(super) mod jay_head_ext_format_info_v1; +pub(super) mod jay_head_ext_jay_tearing_mode_info_v1; pub(super) mod jay_head_ext_jay_vrr_mode_info_v1; pub(super) mod jay_head_ext_mode_info_v1; pub(super) mod jay_head_ext_mode_setter_v1; diff --git a/src/ifs/head_management/jay_head_ext/jay_head_ext_jay_tearing_mode_info_v1.rs b/src/ifs/head_management/jay_head_ext/jay_head_ext_jay_tearing_mode_info_v1.rs new file mode 100644 index 00000000..efd4cbcd --- /dev/null +++ b/src/ifs/head_management/jay_head_ext/jay_head_ext_jay_tearing_mode_info_v1.rs @@ -0,0 +1,51 @@ +use { + crate::{ + ifs::head_management::HeadState, + wire::{ + jay_head_ext_jay_tearing_mode_info_v1::{ + JayHeadExtJayTearingModeInfoV1RequestHandler, Mode, + }, + jay_head_manager_ext_jay_tearing_mode_info_v1::JayHeadManagerExtJayTearingModeInfoV1RequestHandler, + }, + }, + std::rc::Rc, +}; + +impl_jay_tearing_mode_info_v1! { + version = 1, + after_announce = after_announce, + after_transaction = after_transaction, +} + +impl HeadName { + fn after_announce(&self, shared: &HeadState) { + self.send_mode(shared); + } + + fn after_transaction(&self, shared: &HeadState, tran: &HeadState) { + if shared.tearing_mode != tran.tearing_mode { + self.send_mode(shared); + } + } + + pub(in super::super) fn send_mode(&self, state: &HeadState) { + self.client.event(Mode { + self_id: self.id, + mode: state.tearing_mode.0, + }); + } +} + +impl JayHeadManagerExtJayTearingModeInfoV1RequestHandler for MgrName { + type Error = ErrorName; + + mgr_common_req!(); +} + +impl JayHeadExtJayTearingModeInfoV1RequestHandler for HeadName { + type Error = ErrorName; + + head_common_req!(); +} + +error!(); diff --git a/src/ifs/jay_randr.rs b/src/ifs/jay_randr.rs index ff196dea..29e7ea2f 100644 --- a/src/ifs/jay_randr.rs +++ b/src/ifs/jay_randr.rs @@ -446,8 +446,7 @@ impl JayRandrRequestHandler for JayRandr { let Some(c) = self.get_output_node(req.output) else { return Ok(()); }; - c.global.persistent.tearing_mode.set(mode); - c.update_presentation_type(); + c.set_tearing_mode(mode); return Ok(()); } diff --git a/src/tasks/connector.rs b/src/tasks/connector.rs index 8393f89f..fb9dd1ad 100644 --- a/src/tasks/connector.rs +++ b/src/tasks/connector.rs @@ -63,6 +63,7 @@ pub fn handle(state: &Rc, connector: &Rc) { vrr_mode: Default::default(), tearing_enabled: backend_state.tearing, tearing_active: false, + tearing_mode: Default::default(), format: backend_state.format, color_space: backend_state.color_space, transfer_function: backend_state.transfer_function, diff --git a/src/tree/output.rs b/src/tree/output.rs index e1151073..83927c97 100644 --- a/src/tree/output.rs +++ b/src/tree/output.rs @@ -1335,6 +1335,17 @@ impl OutputNode { .handle_vrr_mode_change(mode.to_config()); } } + + pub fn set_tearing_mode(&self, mode: &'static TearingMode) { + let old = self.global.persistent.tearing_mode.replace(mode); + if old != mode { + self.update_presentation_type(); + self.global + .connector + .head_managers + .handle_tearing_mode_change(mode.to_config()); + } + } } pub struct OutputTitle { @@ -1785,13 +1796,13 @@ impl TearingMode { Some(res) } - pub fn to_config(&self) -> ConfigVrrMode { + pub fn to_config(&self) -> ConfigTearingMode { match self { - Self::NEVER => ConfigVrrMode::NEVER, - Self::ALWAYS => ConfigVrrMode::ALWAYS, - Self::VARIANT_1 => ConfigVrrMode::VARIANT_1, - Self::VARIANT_2 => ConfigVrrMode::VARIANT_2, - Self::VARIANT_3 => ConfigVrrMode::VARIANT_3, + Self::NEVER => ConfigTearingMode::NEVER, + Self::ALWAYS => ConfigTearingMode::ALWAYS, + Self::VARIANT_1 => ConfigTearingMode::VARIANT_1, + Self::VARIANT_2 => ConfigTearingMode::VARIANT_2, + Self::VARIANT_3 => ConfigTearingMode::VARIANT_3, } } } diff --git a/wire/jay_head_ext_jay_tearing_mode_info_v1.txt b/wire/jay_head_ext_jay_tearing_mode_info_v1.txt new file mode 100644 index 00000000..aafc7b68 --- /dev/null +++ b/wire/jay_head_ext_jay_tearing_mode_info_v1.txt @@ -0,0 +1,7 @@ +request destroy (destructor) { + +} + +event mode { + mode: u32, +} diff --git a/wire/jay_head_manager_ext_jay_tearing_mode_info_v1.txt b/wire/jay_head_manager_ext_jay_tearing_mode_info_v1.txt new file mode 100644 index 00000000..b89dc989 --- /dev/null +++ b/wire/jay_head_manager_ext_jay_tearing_mode_info_v1.txt @@ -0,0 +1,7 @@ +request destroy (destructor) { + +} + +event head { + head: id(jay_head_ext_jay_tearing_mode_info_v1) (new), +}