1 | //! Helpers for atomic modesetting. |
2 | |
3 | use control; |
4 | |
5 | /// Helper struct to construct atomic commit requests |
6 | #[derive (Debug, Clone, Default)] |
7 | pub 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 | |
14 | impl 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 | |