From e0f1dd549d7623a833dadd0b3e76ff6ba55f875b Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Mon, 14 Jul 2025 16:47:25 +0200 Subject: [PATCH] head-management: add brightness-info-v1 extension --- src/compositor.rs | 1 + src/ifs/head_management.rs | 24 +++++- .../head_management/head_management_macros.rs | 1 + src/ifs/head_management/jay_head_ext.rs | 1 + .../jay_head_ext_brightness_info_v1.rs | 77 +++++++++++++++++++ .../jay_head_manager_session_v1.rs | 2 + src/tasks/connector.rs | 1 + src/tree/output.rs | 10 ++- wire/jay_head_ext_brightness_info_v1.txt | 15 ++++ ...ay_head_manager_ext_brightness_info_v1.txt | 7 ++ 10 files changed, 136 insertions(+), 3 deletions(-) create mode 100644 src/ifs/head_management/jay_head_ext/jay_head_ext_brightness_info_v1.rs create mode 100644 wire/jay_head_ext_brightness_info_v1.txt create mode 100644 wire/jay_head_manager_ext_brightness_info_v1.txt diff --git a/src/compositor.rs b/src/compositor.rs index 1217fa0f..020b960f 100644 --- a/src/compositor.rs +++ b/src/compositor.rs @@ -662,6 +662,7 @@ fn create_dummy_output(state: &Rc) { color_space: backend_state.color_space, transfer_function: backend_state.transfer_function, supported_formats: Default::default(), + brightness: None, }; let connector_data = Rc::new(ConnectorData { id, diff --git a/src/ifs/head_management.rs b/src/ifs/head_management.rs index d3d734b9..93facc4e 100644 --- a/src/ifs/head_management.rs +++ b/src/ifs/head_management.rs @@ -67,7 +67,7 @@ struct HeadCommon { pending: RefCell>, } -#[derive(Clone, Eq, PartialEq)] +#[derive(Clone, PartialEq)] pub struct HeadState { pub name: RcEq, pub wl_output: Option, @@ -92,6 +92,7 @@ pub struct HeadState { pub color_space: BackendColorSpace, pub transfer_function: BackendTransferFunction, pub supported_formats: RcEq>, + pub brightness: Option, } impl HeadState { @@ -286,6 +287,11 @@ impl HeadManagers { ext.send_supported(state); head.session.schedule_done(); } + if let Some(ext) = &head.ext.brightness_info_v1 { + ext.send_implied_default_brightness(state); + ext.send_brightness(state); + head.session.schedule_done(); + } } } @@ -491,6 +497,10 @@ impl HeadManagers { ext.send_state(state); head.session.schedule_done(); } + if let Some(ext) = &head.ext.brightness_info_v1 { + ext.send_implied_default_brightness(state); + head.session.schedule_done(); + } } } @@ -505,4 +515,16 @@ impl HeadManagers { } } } + + pub fn handle_brightness_change(&self, brightness: Option) { + let state = &mut *self.state.borrow_mut(); + state.brightness = brightness; + for head in self.managers.lock().values() { + skip_in_transaction!(head); + if let Some(ext) = &head.ext.brightness_info_v1 { + ext.send_brightness(state); + head.session.schedule_done(); + } + } + } } diff --git a/src/ifs/head_management/head_management_macros.rs b/src/ifs/head_management/head_management_macros.rs index 99bbe9a1..6c13a37c 100644 --- a/src/ifs/head_management/head_management_macros.rs +++ b/src/ifs/head_management/head_management_macros.rs @@ -410,4 +410,5 @@ declare_extensions! { jay_tearing_mode_setter_v1: JayTearingModeSetterV1, format_setter_v1: FormatSetterV1, drm_color_space_setter_v1: DrmColorSpaceSetterV1, + brightness_info_v1: BrightnessInfoV1, } diff --git a/src/ifs/head_management/jay_head_ext.rs b/src/ifs/head_management/jay_head_ext.rs index a901d8d9..0f797e1e 100644 --- a/src/ifs/head_management/jay_head_ext.rs +++ b/src/ifs/head_management/jay_head_ext.rs @@ -1,3 +1,4 @@ +pub(super) mod jay_head_ext_brightness_info_v1; pub(super) mod jay_head_ext_compositor_space_enabler_v1; pub(super) mod jay_head_ext_compositor_space_info_v1; pub(super) mod jay_head_ext_compositor_space_positioner_v1; diff --git a/src/ifs/head_management/jay_head_ext/jay_head_ext_brightness_info_v1.rs b/src/ifs/head_management/jay_head_ext/jay_head_ext_brightness_info_v1.rs new file mode 100644 index 00000000..d1438f4b --- /dev/null +++ b/src/ifs/head_management/jay_head_ext/jay_head_ext_brightness_info_v1.rs @@ -0,0 +1,77 @@ +use { + crate::{ + backend::BackendTransferFunction, + cmm::cmm_luminance::Luminance, + ifs::head_management::HeadState, + wire::{ + jay_head_ext_brightness_info_v1::{ + Brightness, DefaultBrightness, ImpliedDefaultBrightness, + JayHeadExtBrightnessInfoV1RequestHandler, + }, + jay_head_manager_ext_brightness_info_v1::JayHeadManagerExtBrightnessInfoV1RequestHandler, + }, + }, + std::rc::Rc, +}; + +impl_brightness_info_v1! { + version = 1, + after_announce = after_announce, + after_transaction = after_transaction, +} + +impl HeadName { + fn after_announce(&self, shared: &HeadState) { + self.send_implied_default_brightness(shared); + self.send_brightness(shared); + } + + fn after_transaction(&self, shared: &HeadState, tran: &HeadState) { + if shared.transfer_function != tran.transfer_function { + self.send_implied_default_brightness(shared); + } + if shared.brightness != tran.brightness { + self.send_brightness(shared); + } + } + + pub(in super::super) fn send_implied_default_brightness(&self, shared: &HeadState) { + let lux = match shared.transfer_function { + BackendTransferFunction::Default => shared + .monitor_info + .as_ref() + .and_then(|m| m.luminance.as_ref()) + .map(|l| l.max) + .unwrap_or(Luminance::SRGB.white.0), + BackendTransferFunction::Pq => Luminance::ST2084_PQ.white.0, + }; + self.client.event(ImpliedDefaultBrightness { + self_id: self.id, + lux: (lux as f32).to_bits(), + }) + } + + pub(in super::super) fn send_brightness(&self, shared: &HeadState) { + match shared.brightness { + None => self.client.event(DefaultBrightness { self_id: self.id }), + Some(b) => self.client.event(Brightness { + self_id: self.id, + lux: (b as f32).to_bits(), + }), + } + } +} + +impl JayHeadManagerExtBrightnessInfoV1RequestHandler for MgrName { + type Error = ErrorName; + + mgr_common_req!(); +} + +impl JayHeadExtBrightnessInfoV1RequestHandler for HeadName { + type Error = ErrorName; + + head_common_req!(); +} + +error!(); diff --git a/src/ifs/head_management/jay_head_manager_session_v1.rs b/src/ifs/head_management/jay_head_manager_session_v1.rs index c6fb87f5..7fb77948 100644 --- a/src/ifs/head_management/jay_head_manager_session_v1.rs +++ b/src/ifs/head_management/jay_head_manager_session_v1.rs @@ -392,6 +392,7 @@ impl JayHeadManagerSessionV1RequestHandler for JayHeadManagerSessionV1 { TEARING_MODE_INFO = 1 << 9, FORMAT_INFO = 1 << 10, DRM_COLOR_SPACE_INFO = 1 << 11, + BRIGHTNESS_INFO = 1 << 12, COMPOSITOR_SPACE_INFO_ENABLED = 1 << 13, } for head in self.heads.lock().values() { @@ -452,6 +453,7 @@ impl JayHeadManagerSessionV1RequestHandler for JayHeadManagerSessionV1 { HeadOp::SetTransferFunction(e) => { state.transfer_function = e; to_send |= DRM_COLOR_SPACE_INFO; + to_send |= BRIGHTNESS_INFO; } HeadOp::SetColorSpace(c) => { state.color_space = c; diff --git a/src/tasks/connector.rs b/src/tasks/connector.rs index 668b5fe5..3853a195 100644 --- a/src/tasks/connector.rs +++ b/src/tasks/connector.rs @@ -68,6 +68,7 @@ pub fn handle(state: &Rc, connector: &Rc) { color_space: backend_state.color_space, transfer_function: backend_state.transfer_function, supported_formats: Default::default(), + brightness: None, }; let data = Rc::new(ConnectorData { id, diff --git a/src/tree/output.rs b/src/tree/output.rs index 83927c97..dd2aa0a0 100644 --- a/src/tree/output.rs +++ b/src/tree/output.rs @@ -913,8 +913,14 @@ impl OutputNode { } pub fn set_brightness(&self, brightness: Option) { - self.global.persistent.brightness.set(brightness); - self.update_color_description(); + let old = self.global.persistent.brightness.replace(brightness); + if old != brightness { + self.update_color_description(); + self.global + .connector + .head_managers + .handle_brightness_change(brightness); + } } fn find_stacked_at( diff --git a/wire/jay_head_ext_brightness_info_v1.txt b/wire/jay_head_ext_brightness_info_v1.txt new file mode 100644 index 00000000..95b6bdcf --- /dev/null +++ b/wire/jay_head_ext_brightness_info_v1.txt @@ -0,0 +1,15 @@ +request destroy (destructor) { + +} + +event implied_default_brightness { + lux: u32, +} + +event default_brightness { + +} + +event brightness { + lux: u32, +} diff --git a/wire/jay_head_manager_ext_brightness_info_v1.txt b/wire/jay_head_manager_ext_brightness_info_v1.txt new file mode 100644 index 00000000..b8271532 --- /dev/null +++ b/wire/jay_head_manager_ext_brightness_info_v1.txt @@ -0,0 +1,7 @@ +request destroy (destructor) { + +} + +event head { + head: id(jay_head_ext_brightness_info_v1) (new), +}