drm/control/
atomic.rs

1//! Helpers for atomic modesetting.
2
3use crate::control;
4
5/// Helper struct to construct atomic commit requests
6#[derive(Debug, Clone, Default)]
7pub struct AtomicModeReq {
8    pub(super) objects: Vec<control::RawResourceHandle>,
9    pub(super) count_props_per_object: Vec<u32>,
10    pub(super) props: Vec<control::property::Handle>,
11    pub(super) values: Vec<control::property::RawValue>,
12}
13
14impl AtomicModeReq {
15    /// Create a new and empty atomic commit request
16    pub fn new() -> AtomicModeReq {
17        Self::default()
18    }
19
20    /// Add a property and value pair for a given raw resource to the request
21    pub fn add_raw_property(
22        &mut self,
23        obj_id: control::RawResourceHandle,
24        prop_id: control::property::Handle,
25        value: control::property::RawValue,
26    ) {
27        // add object if missing (also to count_props_per_object)
28        let (idx, prop_count) = match self.objects.binary_search(&obj_id) {
29            Ok(idx) => (idx, self.count_props_per_object[idx]),
30            Err(new_idx) => {
31                self.objects.insert(new_idx, obj_id);
32                self.count_props_per_object.insert(new_idx, 0);
33                (new_idx, 0)
34            }
35        };
36
37        // get start of our objects props
38        let prop_slice_start = self.count_props_per_object.iter().take(idx).sum::<u32>() as usize;
39        // get end
40        let prop_slice_end = prop_slice_start + prop_count as usize;
41
42        // search for existing prop entry
43        match self.props[prop_slice_start..prop_slice_end]
44            .binary_search_by_key(&Into::<u32>::into(prop_id), |x| (*x).into())
45        {
46            // prop exists, override
47            Ok(prop_idx) => {
48                self.values[prop_slice_start + prop_idx] = value;
49            }
50            Err(prop_idx) => {
51                // increase prop count
52                self.count_props_per_object[idx] += 1;
53                // insert prop, insert value
54                self.props.insert(prop_slice_start + prop_idx, prop_id);
55                self.values.insert(prop_slice_start + prop_idx, value);
56            }
57        }
58    }
59
60    /// Add a property and value pair for a given handle to the request
61    pub fn add_property<H>(
62        &mut self,
63        handle: H,
64        property: control::property::Handle,
65        value: control::property::Value,
66    ) where
67        H: control::ResourceHandle,
68    {
69        self.add_raw_property(handle.into(), property, value.into())
70    }
71}