1 //! Helpers for atomic modesetting. 2 3 use crate::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 new() -> AtomicModeReq16 pub fn new() -> AtomicModeReq { 17 Self::default() 18 } 19 20 /// Add a property and value pair for a given raw resource to the request add_raw_property( &mut self, obj_id: control::RawResourceHandle, prop_id: control::property::Handle, value: control::property::RawValue, )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 add_property<H>( &mut self, handle: H, property: control::property::Handle, value: control::property::Value, ) where H: control::ResourceHandle,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