1
0
Fork 0
forked from wry/wry
wry/src/backends/metal/video/properties.rs

144 lines
4.1 KiB
Rust

use {
crate::video::drm::{
DrmError, DrmMaster, DrmObject, DrmProperty, DrmPropertyDefinition, DrmPropertyType,
},
ahash::AHashMap,
bstr::{BString, ByteSlice},
std::rc::Rc,
};
#[derive(Debug)]
pub struct DefaultProperty {
pub name: &'static str,
pub prop: DrmProperty,
pub value: u64,
}
#[derive(Copy, Clone)]
pub(super) enum DefaultValue {
Fixed(u64),
Enum(&'static str),
Bitmask(&'static [&'static str]),
RangeMax,
}
pub(super) fn create_default_properties(
props: &CollectedProperties,
defaults: &[(&'static str, DefaultValue)],
) -> Vec<DefaultProperty> {
let mut res = vec![];
let mut defaults = defaults.iter();
'outer: loop {
let Some(&(name, def)) = defaults.next() else {
break;
};
if let Some((definition, _)) = props.props.get(name.as_bytes().as_bstr()) {
let value = match def {
DefaultValue::Fixed(v) => v,
DefaultValue::Enum(e) => match &definition.ty {
DrmPropertyType::Enum {
values,
bitmask: false,
} => match values.iter().find(|v| v.name == e) {
None => continue,
Some(v) => v.value,
},
_ => continue,
},
DefaultValue::Bitmask(e) => match &definition.ty {
DrmPropertyType::Enum {
values,
bitmask: true,
} => {
let mut res = 0;
for &e in e {
match values.iter().find(|v| v.name == e) {
None => continue 'outer,
Some(v) => res |= 1 << v.value,
}
}
res
}
_ => continue,
},
DefaultValue::RangeMax => match &definition.ty {
DrmPropertyType::Range { max, .. } => *max,
DrmPropertyType::SignedRange { max, .. } => *max as u64,
_ => continue,
},
};
res.push(DefaultProperty {
name,
prop: definition.id,
value,
});
}
}
res
}
pub(super) fn collect_properties<T: DrmObject>(
master: &Rc<DrmMaster>,
t: T,
) -> Result<CollectedProperties, DrmError> {
let mut props = AHashMap::new();
for prop in master.get_properties(t)? {
let def = master.get_property(prop.id)?;
props.insert(def.name.clone(), (def, prop.value));
}
Ok(CollectedProperties { props })
}
pub(super) fn collect_untyped_properties<T: DrmObject>(
master: &Rc<DrmMaster>,
t: T,
props: &mut AHashMap<DrmProperty, u64>,
) -> Result<(), DrmError> {
props.clear();
for prop in master.get_properties(t)? {
props.insert(prop.id, prop.value);
}
Ok(())
}
pub(super) struct CollectedProperties {
pub(super) props: AHashMap<BString, (DrmPropertyDefinition, u64)>,
}
impl CollectedProperties {
pub(super) fn get(&self, name: &str) -> Result<TypedProperty<u64>, DrmError> {
match self.props.get(name.as_bytes().as_bstr()) {
Some((def, value)) => Ok(TypedProperty {
id: def.id,
value: *value,
}),
_ => Err(DrmError::MissingProperty(name.to_string().into_boxed_str())),
}
}
pub(super) fn to_untyped(&self) -> AHashMap<DrmProperty, u64> {
let mut res = AHashMap::new();
for (def, val) in self.props.values() {
res.insert(def.id, *val);
}
res
}
}
#[derive(Copy, Clone, Debug)]
pub struct TypedProperty<T> {
pub id: DrmProperty,
pub value: T,
}
impl<T: Copy> TypedProperty<T> {
pub(super) fn map<U, F>(self, f: F) -> TypedProperty<U>
where
F: FnOnce(T) -> U,
{
TypedProperty {
id: self.id,
value: f(self.value),
}
}
}