1//! Helpers for atomic modesetting.
2
3use 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}
72