1
0
Fork 0
forked from wry/wry

head-management: add drm-color-space-info-v1 extension

This commit is contained in:
Julian Orth 2025-07-14 11:03:34 +02:00
parent 1195613fc6
commit 6647b93e1e
9 changed files with 117 additions and 1 deletions

View file

@ -657,6 +657,8 @@ fn create_dummy_output(state: &Rc<State>) {
tearing_enabled: backend_state.tearing,
tearing_active: false,
format: XRGB8888,
color_space: backend_state.color_space,
transfer_function: backend_state.transfer_function,
};
let connector_data = Rc::new(ConnectorData {
id,

View file

@ -1,6 +1,9 @@
use {
crate::{
backend::{ConnectorId, Mode, MonitorInfo, transaction::BackendConnectorTransactionError},
backend::{
BackendColorSpace, BackendTransferFunction, ConnectorId, Mode, MonitorInfo,
transaction::BackendConnectorTransactionError,
},
client::ClientId,
format::Format,
globals::GlobalName,
@ -84,6 +87,8 @@ pub struct HeadState {
pub tearing_enabled: bool,
pub tearing_active: bool,
pub format: &'static Format,
pub color_space: BackendColorSpace,
pub transfer_function: BackendTransferFunction,
}
impl HeadState {
@ -420,4 +425,21 @@ impl HeadManagers {
}
}
}
pub fn handle_colors_change(
&self,
color_space: BackendColorSpace,
transfer_function: BackendTransferFunction,
) {
let state = &mut *self.state.borrow_mut();
state.color_space = color_space;
state.transfer_function = transfer_function;
for head in self.managers.lock().values() {
skip_in_transaction!(head);
if let Some(ext) = &head.ext.drm_color_space_info_v1 {
ext.send_state(state);
head.session.schedule_done();
}
}
}
}

View file

@ -402,4 +402,5 @@ declare_extensions! {
vrr_state_v1: VrrStateV1,
tearing_state_v1: TearingStateV1,
format_info_v1: FormatInfoV1,
drm_color_space_info_v1: DrmColorSpaceInfoV1,
}

View file

@ -5,6 +5,7 @@ pub(super) mod jay_head_ext_compositor_space_scaler_v1;
pub(super) mod jay_head_ext_compositor_space_transformer_v1;
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_mode_info_v1;
pub(super) mod jay_head_ext_mode_setter_v1;

View file

@ -0,0 +1,66 @@
use {
crate::{
backend::CONCAP_CONNECTOR,
ifs::head_management::{HeadCommon, HeadState},
state::ConnectorData,
wire::{
jay_head_ext_drm_color_space_info_v1::{
Colorimetry, HdmiEotf, JayHeadExtDrmColorSpaceInfoV1RequestHandler,
},
jay_head_manager_ext_drm_color_space_info_v1::JayHeadManagerExtDrmColorSpaceInfoV1RequestHandler,
},
},
std::rc::Rc,
};
impl_drm_color_space_info_v1! {
version = 1,
filter = filter,
after_announce = after_announce,
after_transaction = after_transaction,
}
impl MgrName {
fn filter(&self, connector: &ConnectorData, _common: &Rc<HeadCommon>) -> bool {
connector.connector.caps().contains(CONCAP_CONNECTOR)
}
}
impl HeadName {
fn after_announce(&self, shared: &HeadState) {
self.send_state(shared);
}
fn after_transaction(&self, shared: &HeadState, tran: &HeadState) {
if (shared.color_space, shared.transfer_function)
!= (tran.color_space, tran.transfer_function)
{
self.send_state(shared);
}
}
pub(in super::super) fn send_state(&self, state: &HeadState) {
self.client.event(HdmiEotf {
self_id: self.id,
eotf: state.transfer_function.to_drm() as u32,
});
self.client.event(Colorimetry {
self_id: self.id,
colorimetry: state.color_space.to_drm() as u32,
});
}
}
impl JayHeadManagerExtDrmColorSpaceInfoV1RequestHandler for MgrName {
type Error = ErrorName;
mgr_common_req!();
}
impl JayHeadExtDrmColorSpaceInfoV1RequestHandler for HeadName {
type Error = ErrorName;
head_common_req!();
}
error!();

View file

@ -462,6 +462,10 @@ impl ConnectorData {
if old.format != s.format {
self.head_managers.handle_format_change(s.format);
}
if (old.color_space, old.transfer_function) != (s.color_space, s.transfer_function) {
self.head_managers
.handle_colors_change(s.color_space, s.transfer_function);
}
if let Some(output) = state.outputs.get(&self.connector.id())
&& let Some(node) = &output.node
{

View file

@ -63,6 +63,8 @@ pub fn handle(state: &Rc<State>, connector: &Rc<dyn Connector>) {
tearing_enabled: backend_state.tearing,
tearing_active: false,
format: backend_state.format,
color_space: backend_state.color_space,
transfer_function: backend_state.transfer_function,
};
let data = Rc::new(ConnectorData {
id,

View file

@ -0,0 +1,11 @@
request destroy (destructor) {
}
event hdmi_eotf {
eotf: u32,
}
event colorimetry {
colorimetry: u32,
}

View file

@ -0,0 +1,7 @@
request destroy (destructor) {
}
event head {
head: id(jay_head_ext_drm_color_space_info_v1) (new),
}