diff --git a/drivers/graphics/driver-graphics/src/kms/objects.rs b/drivers/graphics/driver-graphics/src/kms/objects.rs index a56c587f8d..fe343e80b7 100644 --- a/drivers/graphics/driver-graphics/src/kms/objects.rs +++ b/drivers/graphics/driver-graphics/src/kms/objects.rs @@ -7,12 +7,14 @@ use drm_fourcc::DrmFourcc; use drm_sys::{ drm_mode_modeinfo, DRM_MODE_OBJECT_BLOB, DRM_MODE_OBJECT_CONNECTOR, DRM_MODE_OBJECT_CRTC, DRM_MODE_OBJECT_ENCODER, DRM_MODE_OBJECT_FB, DRM_MODE_OBJECT_PLANE, DRM_MODE_OBJECT_PROPERTY, + DRM_PLANE_TYPE_CURSOR, DRM_PLANE_TYPE_OVERLAY, DRM_PLANE_TYPE_PRIMARY, }; use syscall::{Error, Result, ENOENT}; use crate::kms::connector::{KmsConnector, KmsEncoder}; use crate::kms::properties::{ - define_object_props, init_standard_props, KmsBlob, KmsProperty, KmsPropertyData, ACTIVE, + define_object_props, init_standard_props, type_, KmsBlob, KmsProperty, KmsPropertyData, ACTIVE, + CRTC_H, CRTC_ID, CRTC_W, CRTC_X, CRTC_Y, FB_ID, SRC_H, SRC_W, SRC_X, SRC_Y, }; use crate::GraphicsAdapter; @@ -141,6 +143,7 @@ impl KmsObjects { plane_index, possible_crtcs, plane_type, + properties: KmsPlane::base_properties(), state: KmsPlaneState { fb_id: None, crtc_id: None, @@ -312,6 +315,7 @@ pub struct KmsPlane { pub plane_index: u32, pub possible_crtcs: u32, pub plane_type: KmsPlaneType, + pub properties: Vec>, pub state: KmsPlaneState, pub driver_data: T::Plane, } @@ -337,11 +341,48 @@ impl Clone for KmsPlaneState { } } -#[derive(Debug, PartialEq)] +define_object_props!(object, KmsPlane { + type_ { + get => object.plane_type as u64, + } + FB_ID { + get => u64::from(object.state.fb_id.map_or(0, |id| id.0)), + } + CRTC_ID { + get => u64::from(object.state.crtc_id.map_or(0, |id| id.0)), + } + CRTC_X { + get => u64::from(object.state.crtc_rect.x.cast_unsigned()), + } + CRTC_Y { + get => u64::from(object.state.crtc_rect.y.cast_unsigned()), + } + CRTC_W { + get => u64::from(object.state.crtc_rect.width), + } + CRTC_H { + get => u64::from(object.state.crtc_rect.height), + } + SRC_X { + get => u64::from(object.state.src_rect.x), + } + SRC_Y { + get => u64::from(object.state.src_rect.y), + } + SRC_W { + get => u64::from(object.state.src_rect.width), + } + SRC_H { + get => u64::from(object.state.src_rect.height), + } +}); + +#[derive(Copy, Clone, Debug, PartialEq)] +#[repr(u32)] pub enum KmsPlaneType { - Primary, - Overlay, - Cursor, + Primary = DRM_PLANE_TYPE_PRIMARY, + Overlay = DRM_PLANE_TYPE_OVERLAY, + Cursor = DRM_PLANE_TYPE_CURSOR, } #[derive(Debug, Clone)] diff --git a/drivers/graphics/driver-graphics/src/kms/properties.rs b/drivers/graphics/driver-graphics/src/kms/properties.rs index bcd16005c7..deca140d26 100644 --- a/drivers/graphics/driver-graphics/src/kms/properties.rs +++ b/drivers/graphics/driver-graphics/src/kms/properties.rs @@ -69,8 +69,15 @@ impl KmsObjects { .map(|prop| (prop.id.0, (prop.getter)(&connector))) .unzip()) } + KmsObject::Plane(plane) => { + let plane = plane.lock().unwrap(); + Ok(plane + .properties + .iter() + .map(|prop| (prop.id.0, (prop.getter)(&plane))) + .unzip()) + } KmsObject::Encoder(_) - | KmsObject::Plane(_) | KmsObject::Property(_) | KmsObject::Framebuffer(_) | KmsObject::Blob(_) => Ok((vec![], vec![])), diff --git a/drivers/graphics/driver-graphics/src/lib.rs b/drivers/graphics/driver-graphics/src/lib.rs index faa60879cc..321cdb3096 100644 --- a/drivers/graphics/driver-graphics/src/lib.rs +++ b/drivers/graphics/driver-graphics/src/lib.rs @@ -293,15 +293,17 @@ struct VtState { } enum Handle { - V2 { - vt: usize, - unique: Option, - next_id: u32, - buffers: HashMap>, - }, + V2(DrmHandle), SchemeRoot, } +struct DrmHandle { + vt: usize, + unique: Option, + next_id: u32, + buffers: HashMap>, +} + impl GraphicsSchemeInner { fn get_or_create_vt<'a>( adapter: &T, @@ -440,12 +442,12 @@ impl SchemeSync for GraphicsSchemeInner { // Ensure the VT exists such that the rest of the methods can freely access it. Self::get_or_create_vt(&self.adapter, &self.objects, &mut self.vts, vt); - Handle::V2 { + Handle::V2(DrmHandle { vt, unique: None, next_id: 0, buffers: HashMap::new(), - } + }) } else { return Err(Error::new(EINVAL)); }; @@ -464,12 +466,12 @@ impl SchemeSync for GraphicsSchemeInner { fn fpath(&mut self, id: usize, buf: &mut [u8], _ctx: &CallerCtx) -> syscall::Result { FpathWriter::with(buf, &self.scheme_name, |w| { match self.handles.get(id)? { - Handle::V2 { + Handle::V2(DrmHandle { vt, unique: _, next_id: _, buffers: _, - } => write!(w, "v2/{vt}").unwrap(), + }) => write!(w, "v2/{vt}").unwrap(), Handle::SchemeRoot => return Err(Error::new(EOPNOTSUPP)), }; Ok(()) @@ -487,12 +489,7 @@ impl SchemeSync for GraphicsSchemeInner { match self.handles.get_mut(id)? { Handle::SchemeRoot => return Err(Error::new(EOPNOTSUPP)), - Handle::V2 { - vt, - unique, - next_id, - buffers, - } => match metadata[0] { + Handle::V2(handle) => match metadata[0] { ipc::VERSION => ipc::DrmVersion::with(payload, |mut data| { data.set_version_major(1); data.set_version_minor(4); @@ -505,7 +502,7 @@ impl SchemeSync for GraphicsSchemeInner { Ok(0) }), ipc::GET_UNIQUE => ipc::DrmUnique::with(payload, |mut data| { - if let Some(unique) = unique { + if let Some(unique) = &handle.unique { data.set_unique(unsafe { mem::transmute::<&[u8], &[c_char]>(unique.as_bytes()) }); @@ -527,7 +524,7 @@ impl SchemeSync for GraphicsSchemeInner { data.set_drm_dd_major(1); data.set_drm_dd_minor(4); - *unique = Some(self.adapter.get_unique()); + handle.unique = Some(self.adapter.get_unique()); Ok(0) }), @@ -643,7 +640,7 @@ impl SchemeSync for GraphicsSchemeInner { let mut new_plane_state = plane.lock().unwrap().state.clone(); new_plane_state.fb_id = fb_id; new_plane_state.crtc_id = Some(crtc_id); - if *vt == self.active_vt { + if handle.vt == self.active_vt { self.adapter .set_crtc(&self.objects, crtc, new_crtc_state.clone())?; self.adapter.set_plane( @@ -668,14 +665,14 @@ impl SchemeSync for GraphicsSchemeInner { } crtc.lock().unwrap().state = new_crtc_state.clone(); plane.lock().unwrap().state = new_plane_state.clone(); - self.vts.get_mut(vt).unwrap().crtc_state + self.vts.get_mut(&handle.vt).unwrap().crtc_state [crtc.lock().unwrap().crtc_index as usize] = new_crtc_state; - self.vts.get_mut(vt).unwrap().plane_state + self.vts.get_mut(&handle.vt).unwrap().plane_state [plane.lock().unwrap().plane_index as usize] = new_plane_state; Ok(0) }), ipc::MODE_CURSOR => ipc::DrmModeCursor::with(payload, |data| { - let vt_state = self.vts.get_mut(vt).unwrap(); + let vt_state = self.vts.get_mut(&handle.vt).unwrap(); let Some(cursor_plane) = &mut vt_state.cursor_plane else { return Err(Error::new(ENXIO)); @@ -685,7 +682,7 @@ impl SchemeSync for GraphicsSchemeInner { if update_buffer { cursor_plane.buffer = if data.handle() == 0 { None - } else if let Some(buffer) = buffers.get(&data.handle()) { + } else if let Some(buffer) = handle.buffers.get(&data.handle()) { Some(buffer.clone()) } else { return Err(Error::new(ENOENT)); @@ -815,19 +812,22 @@ impl SchemeSync for GraphicsSchemeInner { _ => todo!(), }; - *next_id += 1; - buffers.insert(*next_id, fb.buffer.clone()); + handle.next_id += 1; + handle.buffers.insert(handle.next_id, fb.buffer.clone()); data.set_width(fb.width); data.set_height(fb.height); data.set_pitch(fb.pitch); data.set_bpp(bpp); data.set_depth(depth); - data.set_handle(*next_id); + data.set_handle(handle.next_id); Ok(0) }), ipc::MODE_ADD_FB => ipc::DrmModeFbCmd::with(payload, |mut data| { - let buffer = buffers.get(&data.handle()).ok_or(Error::new(EINVAL))?; + let buffer = handle + .buffers + .get(&data.handle()) + .ok_or(Error::new(EINVAL))?; if data.bpp() != 32 { return Err(Error::new(EINVAL)); @@ -907,7 +907,7 @@ impl SchemeSync for GraphicsSchemeInner { height: fb.height, }); - if *vt == self.active_vt { + if handle.vt == self.active_vt { for plane in self.objects.planes() { let state = plane.lock().unwrap().state.clone(); if state.fb_id == Some(KmsObjectId(data.fb_id())) { @@ -930,9 +930,9 @@ impl SchemeSync for GraphicsSchemeInner { data.set_pitch(pitch); data.set_size(buffer.size() as u64); - *next_id += 1; - buffers.insert(*next_id, Arc::new(buffer)); - data.set_handle(*next_id as u32); + handle.next_id += 1; + handle.buffers.insert(handle.next_id, Arc::new(buffer)); + data.set_handle(handle.next_id as u32); Ok(0) }), ipc::MODE_MAP_DUMB => ipc::DrmModeMapDumb::with(payload, |mut data| { @@ -942,19 +942,19 @@ impl SchemeSync for GraphicsSchemeInner { let buffer_id = data.handle(); - if !buffers.contains_key(&buffer_id) { + if !handle.buffers.contains_key(&buffer_id) { return Err(Error::new(ENOENT)); } // FIXME use a better scheme for creating map offsets - assert!(buffers[&buffer_id].size() < MAP_FAKE_OFFSET_MULTIPLIER); + assert!(handle.buffers[&buffer_id].size() < MAP_FAKE_OFFSET_MULTIPLIER); data.set_offset((buffer_id as usize * MAP_FAKE_OFFSET_MULTIPLIER) as u64); Ok(0) }), ipc::MODE_DESTROY_DUMB => ipc::DrmModeDestroyDumb::with(payload, |data| { - if buffers.remove(&data.handle()).is_none() { + if handle.buffers.remove(&data.handle()).is_none() { return Err(Error::new(ENOENT)); } Ok(0) @@ -1003,7 +1003,7 @@ impl SchemeSync for GraphicsSchemeInner { height: data.crtc_h(), }; - if *vt == self.active_vt { + if handle.vt == self.active_vt { self.adapter.set_plane( &self.objects, plane, @@ -1016,7 +1016,7 @@ impl SchemeSync for GraphicsSchemeInner { }, )?; } - self.vts.get_mut(vt).unwrap().plane_state + self.vts.get_mut(&handle.vt).unwrap().plane_state [plane.lock().unwrap().plane_index as usize] = new_state; Ok(0) }), @@ -1036,7 +1036,10 @@ impl SchemeSync for GraphicsSchemeInner { ipc::MODE_ADD_FB2 => ipc::DrmModeFbCmd2::with(payload, |mut data| { // FIXME handle multi-plane framebuffers - let buffer = buffers.get(&data.handles()[0]).ok_or(Error::new(EINVAL))?; + let buffer = handle + .buffers + .get(&data.handles()[0]) + .ok_or(Error::new(EINVAL))?; let fb = self.adapter.create_framebuffer(buffer); @@ -1056,13 +1059,6 @@ impl SchemeSync for GraphicsSchemeInner { }), ipc::MODE_OBJ_GET_PROPERTIES => { ipc::DrmModeObjGetProperties::with(payload, |mut data| { - // FIXME remove once all drm objects are materialized in self.objects - if data.obj_id() >= 1 << 11 { - data.set_props_ptr(&[]); - data.set_prop_values_ptr(&[]); - return Ok(0); - } - let (props, prop_vals) = self .objects .get_object_properties_data(KmsObjectId(data.obj_id()))?; @@ -1073,7 +1069,7 @@ impl SchemeSync for GraphicsSchemeInner { }) } ipc::MODE_CURSOR2 => ipc::DrmModeCursor2::with(payload, |data| { - let vt_state = self.vts.get_mut(vt).unwrap(); + let vt_state = self.vts.get_mut(&handle.vt).unwrap(); let Some(cursor_plane) = &mut vt_state.cursor_plane else { return Err(Error::new(ENXIO)); @@ -1083,7 +1079,7 @@ impl SchemeSync for GraphicsSchemeInner { if update_buffer { cursor_plane.buffer = if data.handle() == 0 { None - } else if let Some(buffer) = buffers.get(&data.handle()) { + } else if let Some(buffer) = handle.buffers.get(&data.handle()) { Some(buffer.clone()) } else { return Err(Error::new(ENOENT)); @@ -1104,13 +1100,13 @@ impl SchemeSync for GraphicsSchemeInner { ipc::MODE_GET_FB2 => ipc::DrmModeFbCmd2::with(payload, |mut data| { let fb = self.objects.get_framebuffer(KmsObjectId(data.fb_id()))?; - *next_id += 1; - buffers.insert(*next_id, fb.buffer.clone()); + handle.next_id += 1; + handle.buffers.insert(handle.next_id, fb.buffer.clone()); data.set_width(fb.width); data.set_height(fb.height); data.set_pixel_format(fb.pixel_format as u32); - data.set_handles([*next_id, 0, 0, 0]); + data.set_handles([handle.next_id, 0, 0, 0]); data.set_pitches([fb.pitch, 0, 0, 0]); data.set_offsets([0; 4]); data.set_modifier([0; 4]); @@ -1131,12 +1127,12 @@ impl SchemeSync for GraphicsSchemeInner { ) -> syscall::Result { // log::trace!("KSMSG MMAP {} {:?} {} {}", id, _flags, _offset, _size); let (framebuffer, offset) = match self.handles.get(id)? { - Handle::V2 { + Handle::V2(DrmHandle { vt: _, unique: _, next_id: _, buffers, - } => ( + }) => ( buffers .get(&((offset as usize / MAP_FAKE_OFFSET_MULTIPLIER) as u32)) .ok_or(Error::new(EINVAL))