Skip to content

Commit 25e2e54

Browse files
committed
metal: use PrepareDrmObjectProperties for connector state
1 parent 80e1632 commit 25e2e54

3 files changed

Lines changed: 75 additions & 106 deletions

File tree

src/backends/metal/transaction.rs

Lines changed: 43 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -89,13 +89,9 @@ pub struct DrmCrtcStateProps {
8989
pub gamma_lut_blob_id: Option<DrmPropertyValue<DrmBlob>>,
9090
}
9191

92-
#[derive(Default, Clone, Debug)]
92+
#[derive(Clone, Debug, Reset)]
9393
pub struct DrmConnectorState {
94-
pub link_status: u64,
95-
pub crtc_id: DrmCrtc,
96-
pub color_space: Option<u64>,
9794
pub hdr_metadata: Option<hdr_output_metadata>,
98-
pub hdr_metadata_blob_id: DrmBlob,
9995
pub hdr_metadata_blob: Option<Rc<PropBlob>>,
10096
pub locked: bool,
10197
pub fb: DrmFb,
@@ -111,6 +107,15 @@ pub struct DrmConnectorState {
111107
pub crtc_y: i32,
112108
pub crtc_w: i32,
113109
pub crtc_h: i32,
110+
pub props: DrmConnectorStateProps,
111+
}
112+
113+
#[derive(Clone, Debug, PrepareDrmObjectProperties)]
114+
pub struct DrmConnectorStateProps {
115+
pub link_status: DrmPropertyValue,
116+
pub crtc_id: DrmPropertyValue<DrmCrtc>,
117+
pub color_space: Option<DrmPropertyValue>,
118+
pub hdr_metadata_blob_id: Option<DrmPropertyValue<DrmBlob>>,
114119
}
115120

116121
struct PlaneConfig {
@@ -181,6 +186,7 @@ macro_rules! impl_props_deref {
181186

182187
impl_props_deref!(DrmPlaneState, DrmPlaneStateProps);
183188
impl_props_deref!(DrmCrtcState, DrmCrtcStateProps);
189+
impl_props_deref!(DrmConnectorState, DrmConnectorStateProps);
184190

185191
impl MetalConnector {
186192
pub fn create_transaction(
@@ -299,8 +305,8 @@ impl MetalDeviceTransaction {
299305
unused_crtcs.insert(crtc.obj.id, ());
300306
}
301307
for (_, connector) in &slf.connectors {
302-
unused_crtcs.remove(&connector.new.crtc_id);
303-
if let Some(crtc) = slf.crtcs.get_mut(&connector.new.crtc_id)
308+
unused_crtcs.remove(&connector.new.crtc_id.value);
309+
if let Some(crtc) = slf.crtcs.get_mut(&connector.new.crtc_id.value)
304310
&& crtc.changed.is_empty()
305311
{
306312
crtc.changed.push(connector.changed.clone());
@@ -356,9 +362,9 @@ impl MetalDeviceTransaction {
356362
|| dd.connection != ConnectorStatus::Connected
357363
|| state.non_desktop_override.unwrap_or(dd.non_desktop)
358364
{
359-
if connector.new.crtc_id.is_some() {
360-
unused_crtcs.insert(connector.new.crtc_id, ());
361-
if let Some(crtc) = slf.crtcs.get(&connector.new.crtc_id) {
365+
if connector.new.crtc_id.value.is_some() {
366+
unused_crtcs.insert(connector.new.crtc_id.value, ());
367+
if let Some(crtc) = slf.crtcs.get(&connector.new.crtc_id.value) {
362368
let planes = crtc_planes.get_mut(&crtc.obj.id).unwrap();
363369
for plane in [&mut planes.primary, &mut planes.cursor] {
364370
if plane.is_some() {
@@ -371,11 +377,11 @@ impl MetalDeviceTransaction {
371377
*planes = CrtcPlanes::default();
372378
}
373379
}
374-
connector.new = DrmConnectorState::default();
380+
connector.new.reset();
375381
continue;
376382
}
377-
connector.new.link_status = DRM_LINK_STATUS_GOOD;
378-
if connector.new.crtc_id.is_none() {
383+
connector.new.link_status.value = DRM_LINK_STATUS_GOOD;
384+
if connector.new.crtc_id.value.is_none() {
379385
let crtc_id = 'crtc_id: {
380386
for (crtc, _) in &dd.crtcs {
381387
if unused_crtcs.contains(crtc) {
@@ -387,9 +393,9 @@ impl MetalDeviceTransaction {
387393
));
388394
};
389395
unused_crtcs.remove(crtc_id);
390-
connector.new.crtc_id = *crtc_id;
396+
connector.new.crtc_id.value = *crtc_id;
391397
}
392-
let crtc = slf.crtcs.get_mut(&connector.new.crtc_id).unwrap();
398+
let crtc = slf.crtcs.get_mut(&connector.new.crtc_id.value).unwrap();
393399
crtc.new.active.value = state.active;
394400
crtc.new.assigned_connector = connector.obj.id;
395401
crtc.changed.push(connector.changed.clone());
@@ -767,9 +773,9 @@ impl MetalDeviceTransaction {
767773
}
768774
}
769775
if let Some(cs) = &mut connector.new.color_space {
770-
*cs = state.color_space.to_drm();
776+
cs.value = state.color_space.to_drm();
771777
}
772-
if dd.hdr_metadata.is_some() {
778+
if let Some(prop) = &mut connector.new.props.hdr_metadata_blob_id {
773779
let new = if state.eotf == BackendEotfs::Default {
774780
None
775781
} else {
@@ -783,15 +789,15 @@ impl MetalDeviceTransaction {
783789
.master
784790
.create_blob(new)
785791
.map_err(BackendConnectorTransactionError::CreateHdrMetadataBlob)?;
786-
connector.new.hdr_metadata_blob_id = blob.id();
792+
prop.value = blob.id();
787793
connector.new.hdr_metadata_blob = Some(Rc::new(blob));
788794
} else {
789-
connector.new.hdr_metadata_blob_id = DrmBlob::NONE;
795+
prop.value = DrmBlob::NONE;
790796
connector.new.hdr_metadata_blob = None;
791797
}
792798
connector.new.hdr_metadata = new;
793799
} else if new.is_none() {
794-
connector.new.hdr_metadata_blob_id = DrmBlob::NONE;
800+
prop.value = DrmBlob::NONE;
795801
connector.new.hdr_metadata_blob = None;
796802
}
797803
}
@@ -815,18 +821,6 @@ impl MetalDeviceTransaction {
815821
}
816822
}
817823

818-
macro_rules! log_change {
819-
($o:expr, $n:expr, $field:ident) => {
820-
log::log!(
821-
LEVEL,
822-
"changed {}: {:?} -> {:?}",
823-
stringify!($field),
824-
$o.$field,
825-
$n.$field
826-
);
827-
};
828-
}
829-
830824
impl MetalDeviceTransactionWithDrmState {
831825
pub fn calculate_change(
832826
mut self,
@@ -870,43 +864,26 @@ impl MetalDeviceTransactionWithDrmState {
870864
let mut c = slf.dev.dev.master.change();
871865
for (_, connector) in &mut slf.connectors {
872866
let dd = &*connector.obj.display.borrow();
873-
let n = &mut connector.new;
874-
let o = &dd.drm_state;
875-
let changed = c.change_object(connector.obj.id, |c| {
876-
if n.link_status != o.link_status {
877-
log_change!(o, n, link_status);
878-
c.change(dd.link_status, n.link_status);
879-
}
880-
if n.crtc_id != o.crtc_id {
881-
log_change!(o, n, crtc_id);
882-
c.change(dd.crtc_id, n.crtc_id);
883-
}
884-
if let Some(prop) = &dd.colorspace
885-
&& let Some(new_cs) = n.color_space
886-
&& let Some(old_cs) = o.color_space
887-
&& new_cs != old_cs
888-
{
889-
log_change!(o, n, color_space);
890-
c.change(*prop, new_cs);
891-
}
892-
if let Some(prop) = &dd.hdr_metadata
893-
&& n.hdr_metadata_blob_id != o.hdr_metadata_blob_id
894-
{
895-
log_change!(o, n, hdr_metadata_blob_id);
896-
c.change(*prop, n.hdr_metadata_blob_id);
897-
}
898-
reset_default_properties!(c, &dd.untyped_properties, &dd.default_properties);
899-
});
900-
if changed {
901-
connector.changed.set(true);
902-
}
867+
let n = &connector.new.props;
868+
let o = &dd.drm_state.props;
869+
let untyped_properties = &dd.untyped_properties;
870+
let default_properties = &dd.default_properties;
871+
let changed = n.differs(o)
872+
|| need_reset_default_properties!(untyped_properties, default_properties);
903873
log::log!(
904874
LEVEL,
905875
"connector {:?} (crtc {:?}) {}changed",
906-
connector.obj.id,
907-
connector.new.crtc_id,
876+
connector.obj.id.0,
877+
connector.new.crtc_id.value.0,
908878
if changed { "" } else { "un" },
909879
);
880+
if changed {
881+
c.change_object(connector.obj.id, |c| {
882+
n.prepare_conditional(o, c, LOGGING);
883+
reset_default_properties!(c, untyped_properties, default_properties);
884+
});
885+
connector.changed.set(true);
886+
}
910887
}
911888
for (_, crtc) in &mut slf.crtcs {
912889
let n = &crtc.new.props;
@@ -1023,14 +1000,14 @@ impl MetalDeviceTransactionWithChange {
10231000
continue;
10241001
}
10251002
connector.obj.version.fetch_add(1);
1026-
if connector.new.crtc_id.is_none() {
1003+
if connector.new.crtc_id.value.is_none() {
10271004
connector.obj.crtc.set(None);
10281005
connector.obj.primary_plane.set(None);
10291006
connector.obj.cursor_plane.set(None);
10301007
connector.obj.buffers.set(None);
10311008
connector.obj.cursor_buffers.set(None);
10321009
} else {
1033-
let crtc = slf.crtcs.get(&connector.new.crtc_id).unwrap();
1010+
let crtc = slf.crtcs.get(&connector.new.crtc_id.value).unwrap();
10341011
crtc.obj.connector.set(Some(connector.obj.clone()));
10351012
connector.obj.crtc.set(Some(crtc.obj.clone()));
10361013
connector.obj.crtc_idle.set(crtc.obj.pending_flip.is_none());

src/backends/metal/video.rs

Lines changed: 20 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ use {
1919
POST_COMMIT_MARGIN_DELTA, PresentFb,
2020
},
2121
transaction::{
22-
DrmConnectorState, DrmCrtcState, DrmCrtcStateProps, DrmPlaneState,
23-
DrmPlaneStateProps, MetalDeviceTransaction,
22+
DrmConnectorState, DrmConnectorStateProps, DrmCrtcState, DrmCrtcStateProps,
23+
DrmPlaneState, DrmPlaneStateProps, MetalDeviceTransaction,
2424
},
2525
},
2626
cmm::{cmm_description::ColorDescription, cmm_primaries::Primaries},
@@ -366,8 +366,6 @@ pub struct DefaultProperty {
366366

367367
#[derive(Debug)]
368368
pub struct ConnectorDisplayData {
369-
pub link_status: DrmProperty,
370-
pub crtc_id: DrmProperty,
371369
pub crtcs: BinarySearchMap<DrmCrtc, Rc<MetalCrtc>, 8>,
372370
pub first_mode: Mode,
373371
pub modes: Vec<DrmModeInfo>,
@@ -393,18 +391,16 @@ pub struct ConnectorDisplayData {
393391
pub primaries: Primaries,
394392
pub luminance: Option<BackendLuminance>,
395393

396-
pub colorspace: Option<DrmProperty>,
397-
pub hdr_metadata: Option<DrmProperty>,
398394
pub drm_state: DrmConnectorState,
399395
}
400396

401397
impl ConnectorDisplayData {
402398
fn update_refresh(&mut self, dev: &MetalDrmDevice) {
403399
self.refresh = 0;
404-
if self.drm_state.crtc_id.is_none() {
400+
if self.drm_state.crtc_id.value.is_none() {
405401
return;
406402
}
407-
let Some(crtc) = dev.crtcs.get(&self.drm_state.crtc_id) else {
403+
let Some(crtc) = dev.crtcs.get(&self.drm_state.crtc_id.value) else {
408404
return;
409405
};
410406
let drm_state = &*crtc.drm_state.borrow();
@@ -1370,9 +1366,7 @@ fn create_connector_display_data(
13701366
.map(|p| p.map(|v| DrmBlob(v as _)))
13711367
.ok();
13721368
let mut hdr_metadata = None;
1373-
let mut hdr_metadata_blob_id = DrmBlob::NONE;
13741369
if let Some(p) = &hdr_metadata_prop {
1375-
hdr_metadata_blob_id = p.value;
13761370
hdr_metadata = Some(hdr_output_metadata::from_eotf(
13771371
HDMI_EOTF_TRADITIONAL_GAMMA_SDR,
13781372
));
@@ -1389,11 +1383,7 @@ fn create_connector_display_data(
13891383
let link_status = props.get("link-status")?;
13901384
let crtc_id = props.get("CRTC_ID")?.map(|v| DrmCrtc(v as _));
13911385
let drm_state = DrmConnectorState {
1392-
link_status: link_status.value,
1393-
crtc_id: crtc_id.value,
1394-
color_space: colorspace_prop.map(|p| p.value),
13951386
hdr_metadata,
1396-
hdr_metadata_blob_id,
13971387
hdr_metadata_blob: None,
13981388
locked: true,
13991389
fb: DrmFb::NONE,
@@ -1409,10 +1399,14 @@ fn create_connector_display_data(
14091399
crtc_y: 0,
14101400
crtc_w: 0,
14111401
crtc_h: 0,
1402+
props: DrmConnectorStateProps {
1403+
link_status,
1404+
crtc_id,
1405+
color_space: colorspace_prop,
1406+
hdr_metadata_blob_id: hdr_metadata_prop,
1407+
},
14121408
};
14131409
Ok(ConnectorDisplayData {
1414-
link_status: link_status.id,
1415-
crtc_id: props.get("CRTC_ID")?.id,
14161410
crtcs,
14171411
first_mode,
14181412
modes: info.modes,
@@ -1434,8 +1428,6 @@ fn create_connector_display_data(
14341428
luminance,
14351429
connector_id,
14361430
output_id,
1437-
colorspace: colorspace_prop.map(|p| p.id),
1438-
hdr_metadata: hdr_metadata_prop.map(|p| p.id),
14391431
drm_state,
14401432
})
14411433
}
@@ -2086,31 +2078,23 @@ impl MetalBackend {
20862078

20872079
impl MetalConnector {
20882080
fn update_properties(&self) -> Result<(), DrmError> {
2089-
let get = |p: &BHashMap<DrmProperty, _>, k: DrmProperty| match p.get(&k) {
2090-
Some(v) => Ok(*v),
2091-
_ => todo!(),
2092-
};
20932081
let master = &self.dev.master;
20942082
let dd = &mut *self.display.borrow_mut();
20952083
collect_untyped_properties(master, self.id, &mut dd.untyped_properties)?;
20962084
let props = &dd.untyped_properties;
20972085
let state = &mut dd.drm_state;
2098-
state.link_status = get(props, dd.link_status)?;
2099-
state.crtc_id = DrmCrtc(get(props, dd.crtc_id)? as _);
2100-
if let Some(cs) = dd.colorspace {
2101-
state.color_space = Some(get(props, cs)?);
2102-
} else {
2103-
state.color_space = None;
2104-
}
2105-
if let Some(meta) = dd.hdr_metadata {
2106-
let id = DrmBlob(get(props, meta)? as _);
2107-
let old = state.hdr_metadata_blob_id;
2108-
state.hdr_metadata_blob_id = id;
2109-
if old != id {
2086+
let old_hdr_metadata_id = state
2087+
.hdr_metadata_blob_id
2088+
.map(|v| v.value)
2089+
.unwrap_or_default();
2090+
state.update(props);
2091+
if let Some(prop) = &state.props.hdr_metadata_blob_id {
2092+
let new_hdr_metadata_id = prop.value;
2093+
if old_hdr_metadata_id != new_hdr_metadata_id {
21102094
state.hdr_metadata = None;
21112095
state.hdr_metadata_blob = None;
2112-
if id.is_some() {
2113-
match master.getblob::<hdr_output_metadata>(id) {
2096+
if new_hdr_metadata_id.is_some() {
2097+
match master.getblob::<hdr_output_metadata>(new_hdr_metadata_id) {
21142098
Ok(b) => {
21152099
state.hdr_metadata = Some(b);
21162100
}

src/utils/reset.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,20 @@ impl Reset for bool {
3838
}
3939
}
4040

41-
impl Reset for i32 {
42-
fn reset(&mut self) {
43-
*self = 0;
44-
}
41+
macro_rules! num {
42+
($ty:ty) => {
43+
impl Reset for $ty {
44+
fn reset(&mut self) {
45+
*self = 0;
46+
}
47+
}
48+
};
4549
}
4650

51+
num!(i32);
52+
num!(u32);
53+
num!(u64);
54+
4755
macro_rules! tuples {
4856
($($id:ident,)*) => {
4957
impl<$($id,)*> Reset for ($($id,)*) where $($id: Reset,)* {

0 commit comments

Comments
 (0)