driver/graphics: Ensure determinstic iteration order for resources

This commit is contained in:
bjorn3
2025-12-20 20:57:47 +01:00
parent 521fd433b9
commit 15fb94aabb
3 changed files with 26 additions and 32 deletions
+3 -3
View File
@@ -114,9 +114,7 @@ impl<T: GraphicsAdapter> GraphicsScheme<T> {
let mut objects = DrmObjects::new();
adapter.init(&mut objects);
for connector in objects.connectors_mut() {
adapter.probe_connector(connector);
}
objects.for_each_connector_mut(|connector| adapter.probe_connector(connector));
GraphicsScheme {
adapter,
@@ -532,12 +530,14 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsScheme<T> {
let conn_ids = self
.objects
.connector_ids()
.iter()
.map(|id| id.0)
.collect::<Vec<_>>();
let mut crtc_ids = Vec::with_capacity(count);
let enc_ids = self
.objects
.encoder_ids()
.iter()
.map(|id| id.0)
.collect::<Vec<_>>();
let mut fb_ids = Vec::with_capacity(count);
+22 -26
View File
@@ -8,6 +8,8 @@ use crate::GraphicsAdapter;
#[derive(Debug)]
pub struct DrmObjects<T: GraphicsAdapter> {
next_id: DrmObjectId,
connectors: Vec<DrmObjectId>,
encoders: Vec<DrmObjectId>,
objects: HashMap<DrmObjectId, DrmObject<T>>,
}
@@ -15,6 +17,8 @@ impl<T: GraphicsAdapter> DrmObjects<T> {
pub(crate) fn new() -> Self {
DrmObjects {
next_id: DrmObjectId(1),
connectors: vec![],
encoders: vec![],
objects: HashMap::new(),
}
}
@@ -38,6 +42,7 @@ impl<T: GraphicsAdapter> DrmObjects<T> {
}),
},
);
self.connectors.push(connector_id);
self.objects.insert(
encoder_id,
@@ -49,36 +54,32 @@ impl<T: GraphicsAdapter> DrmObjects<T> {
}),
},
);
self.encoders.push(encoder_id);
self.next_id.0 += 2;
connector_id
}
pub fn connector_ids(&self) -> impl Iterator<Item = DrmObjectId> + use<'_, T> {
self.objects
.iter()
.filter_map(|(&id, object)| match object.kind {
DrmObjectKind::Connector(_) => Some(id),
_ => None,
})
pub fn connector_ids(&self) -> &[DrmObjectId] {
&self.connectors
}
pub fn connectors(&self) -> impl Iterator<Item = &DrmConnector<T>> + use<'_, T> {
self.objects
.values()
.filter_map(|object| match &object.kind {
DrmObjectKind::Connector(connector) => Some(connector),
_ => None,
self.connectors
.iter()
.map(|&id| match &self.objects[&id].kind {
DrmObjectKind::Connector(connector) => connector,
_ => unreachable!(),
})
}
pub fn connectors_mut(&mut self) -> impl Iterator<Item = &mut DrmConnector<T>> + use<'_, T> {
self.objects
.values_mut()
.filter_map(|object| match &mut object.kind {
DrmObjectKind::Connector(connector) => Some(connector),
_ => None,
})
pub fn for_each_connector_mut<'a>(&mut self, mut f: impl FnMut(&mut DrmConnector<T>)) {
for id in &self.connectors {
match &mut self.objects.get_mut(&id).unwrap().kind {
DrmObjectKind::Connector(connector) => f(connector),
_ => unreachable!(),
}
}
}
pub fn get_connector(&self, id: DrmObjectId) -> Result<&DrmConnector<T>> {
@@ -97,13 +98,8 @@ impl<T: GraphicsAdapter> DrmObjects<T> {
}
}
pub fn encoder_ids(&self) -> impl Iterator<Item = DrmObjectId> + use<'_, T> {
self.objects
.iter()
.filter_map(|(&id, object)| match object.kind {
DrmObjectKind::Encoder(_) => Some(id),
_ => None,
})
pub fn encoder_ids(&self) -> &[DrmObjectId] {
&self.encoders
}
pub fn get_encoder(&self, id: DrmObjectId) -> Result<&DrmEncoder> {
+1 -3
View File
@@ -544,9 +544,7 @@ fn deamon(deamon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> anyhow:
if events & VIRTIO_GPU_EVENT_DISPLAY != 0 {
let (adapter, objects) = scheme.adapter_and_objects_mut();
futures::executor::block_on(async { adapter.update_displays().await.unwrap() });
for connector in objects.connectors_mut() {
adapter.probe_connector(connector);
}
objects.for_each_connector_mut(|connector| adapter.probe_connector(connector));
scheme.notify_displays_changed();
scheme
.adapter_mut()