drivers/graphics/driver-graphics: Move framebuffer ioctls to a separate module
This commit is contained in:
@@ -0,0 +1,196 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use drm_fourcc::DrmFourcc;
|
||||
use syscall::{Error, EINVAL};
|
||||
|
||||
use crate::kms::objects::{KmsFramebuffer, KmsObjectId, KmsObjects};
|
||||
use crate::{Damage, DrmHandle, GraphicsAdapter, VtState};
|
||||
|
||||
pub(super) fn mode_get_fb<T: GraphicsAdapter>(
|
||||
objects: &mut KmsObjects<T>,
|
||||
handle: &mut DrmHandle<T>,
|
||||
mut data: redox_ioctl::drm::DrmModeFbCmd<'_>,
|
||||
) -> Result<usize, Error> {
|
||||
let fb = objects.get_framebuffer(KmsObjectId(data.fb_id()))?;
|
||||
|
||||
let (bpp, depth) = match fb.pixel_format {
|
||||
DrmFourcc::Xrgb8888 => (32, 24),
|
||||
DrmFourcc::Argb8888 => (32, 32),
|
||||
_ => todo!(),
|
||||
};
|
||||
|
||||
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(handle.next_id);
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
pub(super) fn mode_add_fb<T: GraphicsAdapter>(
|
||||
adapter: &mut T,
|
||||
objects: &mut KmsObjects<T>,
|
||||
handle: &mut DrmHandle<T>,
|
||||
mut data: redox_ioctl::drm::DrmModeFbCmd<'_>,
|
||||
) -> Result<usize, Error> {
|
||||
let buffer = handle
|
||||
.buffers
|
||||
.get(&data.handle())
|
||||
.ok_or(Error::new(EINVAL))?;
|
||||
|
||||
if data.bpp() != 32 {
|
||||
return Err(Error::new(EINVAL));
|
||||
}
|
||||
let pixel_format = match data.depth() {
|
||||
24 => DrmFourcc::Xrgb8888,
|
||||
32 => DrmFourcc::Argb8888,
|
||||
_ => return Err(Error::new(EINVAL)),
|
||||
};
|
||||
|
||||
let fb = adapter.create_framebuffer(buffer);
|
||||
|
||||
let id = objects.add_framebuffer(KmsFramebuffer {
|
||||
width: data.width(),
|
||||
height: data.height(),
|
||||
pixel_format,
|
||||
pitch: data.pitch(),
|
||||
buffer: buffer.clone(),
|
||||
driver_data: fb,
|
||||
});
|
||||
|
||||
data.set_fb_id(id.0);
|
||||
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
pub(super) fn mode_rm_fb<T: GraphicsAdapter>(
|
||||
adapter: &mut T,
|
||||
objects: &mut KmsObjects<T>,
|
||||
active_vt: usize,
|
||||
vts: &mut HashMap<usize, VtState<T>>,
|
||||
data: redox_ioctl::drm::StandinForUint<'_>,
|
||||
) -> Result<usize, Error> {
|
||||
let fb_id = KmsObjectId(data.inner());
|
||||
objects.remove_framebuffer(fb_id)?;
|
||||
|
||||
// Disable planes that use this framebuffer.
|
||||
for (vt, vt_data) in vts {
|
||||
for (plane_idx, plane_state) in vt_data.plane_state.iter_mut().enumerate() {
|
||||
if plane_state.fb_id != Some(fb_id) {
|
||||
continue;
|
||||
}
|
||||
plane_state.fb_id = None;
|
||||
|
||||
if *vt != active_vt {
|
||||
continue;
|
||||
}
|
||||
let plane = objects.planes().nth(plane_idx).unwrap();
|
||||
adapter
|
||||
.set_plane(
|
||||
&objects,
|
||||
plane,
|
||||
plane_state.clone(),
|
||||
Damage {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 0,
|
||||
height: 0,
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
pub(super) fn mode_dirtyfb<T: GraphicsAdapter>(
|
||||
adapter: &mut T,
|
||||
objects: &mut KmsObjects<T>,
|
||||
active_vt: usize,
|
||||
handle: &mut DrmHandle<T>,
|
||||
data: redox_ioctl::drm::DrmModeFbDirtyCmd<'_>,
|
||||
) -> Result<usize, Error> {
|
||||
let fb = objects.get_framebuffer(KmsObjectId(data.fb_id()))?;
|
||||
|
||||
let damage = data
|
||||
.clips_ptr()
|
||||
.iter()
|
||||
.map(|rect| Damage {
|
||||
x: u32::from(rect.x1),
|
||||
y: u32::from(rect.y1),
|
||||
width: u32::from(rect.x2 - rect.x1),
|
||||
height: u32::from(rect.y2 - rect.y1),
|
||||
})
|
||||
.reduce(Damage::merge)
|
||||
.unwrap_or(Damage {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: fb.width,
|
||||
height: fb.height,
|
||||
});
|
||||
|
||||
if handle.vt == active_vt {
|
||||
for plane in objects.planes() {
|
||||
let state = plane.lock().unwrap().state.clone();
|
||||
if state.fb_id == Some(KmsObjectId(data.fb_id())) {
|
||||
adapter.set_plane(&objects, plane, state, damage)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
pub(super) fn mode_add_fb2<T: GraphicsAdapter>(
|
||||
adapter: &mut T,
|
||||
objects: &mut KmsObjects<T>,
|
||||
handle: &mut DrmHandle<T>,
|
||||
mut data: redox_ioctl::drm::DrmModeFbCmd2<'_>,
|
||||
) -> Result<usize, Error> {
|
||||
// FIXME handle multi-plane framebuffers
|
||||
|
||||
let buffer = handle
|
||||
.buffers
|
||||
.get(&data.handles()[0])
|
||||
.ok_or(Error::new(EINVAL))?;
|
||||
|
||||
let fb = adapter.create_framebuffer(buffer);
|
||||
|
||||
let id = objects.add_framebuffer(KmsFramebuffer {
|
||||
width: data.width(),
|
||||
height: data.height(),
|
||||
pixel_format: DrmFourcc::try_from(data.pixel_format()).map_err(|_| Error::new(EINVAL))?,
|
||||
pitch: data.pitches()[0],
|
||||
buffer: buffer.clone(),
|
||||
driver_data: fb,
|
||||
});
|
||||
|
||||
data.set_fb_id(id.0);
|
||||
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
pub(super) fn mode_get_fb2<T: GraphicsAdapter>(
|
||||
objects: &mut KmsObjects<T>,
|
||||
handle: &mut DrmHandle<T>,
|
||||
mut data: redox_ioctl::drm::DrmModeFbCmd2<'_>,
|
||||
) -> Result<usize, Error> {
|
||||
let fb = objects.get_framebuffer(KmsObjectId(data.fb_id()))?;
|
||||
|
||||
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([handle.next_id, 0, 0, 0]);
|
||||
data.set_pitches([fb.pitch, 0, 0, 0]);
|
||||
data.set_offsets([0; 4]);
|
||||
data.set_modifier([0; 4]);
|
||||
Ok(0)
|
||||
}
|
||||
@@ -11,10 +11,12 @@ use drm_sys::{
|
||||
};
|
||||
use syscall::{Error, EINVAL, ENOENT, ENXIO};
|
||||
|
||||
use crate::kms::objects::{self, KmsObjectId, KmsObjects, KmsRect};
|
||||
use crate::kms::objects::{KmsObjectId, KmsObjects, KmsRect};
|
||||
use crate::kms::properties::KmsPropertyKind;
|
||||
use crate::{Buffer, Damage, DrmHandle, GraphicsAdapter, VtState, MAP_FAKE_OFFSET_MULTIPLIER};
|
||||
|
||||
mod framebuffer;
|
||||
|
||||
pub(crate) fn call_ioctl<T: GraphicsAdapter>(
|
||||
adapter: &mut T,
|
||||
objects: &mut KmsObjects<T>,
|
||||
@@ -322,120 +324,17 @@ pub(crate) fn call_ioctl<T: GraphicsAdapter>(
|
||||
data.set_data(&blob);
|
||||
Ok(0)
|
||||
}),
|
||||
ipc::MODE_GET_FB => ipc::DrmModeFbCmd::with(payload, |mut data| {
|
||||
let fb = objects.get_framebuffer(KmsObjectId(data.fb_id()))?;
|
||||
|
||||
let (bpp, depth) = match fb.pixel_format {
|
||||
DrmFourcc::Xrgb8888 => (32, 24),
|
||||
DrmFourcc::Argb8888 => (32, 32),
|
||||
_ => todo!(),
|
||||
};
|
||||
|
||||
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(handle.next_id);
|
||||
Ok(0)
|
||||
ipc::MODE_GET_FB => ipc::DrmModeFbCmd::with(payload, |data| {
|
||||
framebuffer::mode_get_fb(objects, handle, data)
|
||||
}),
|
||||
ipc::MODE_ADD_FB => ipc::DrmModeFbCmd::with(payload, |mut data| {
|
||||
let buffer = handle
|
||||
.buffers
|
||||
.get(&data.handle())
|
||||
.ok_or(Error::new(EINVAL))?;
|
||||
|
||||
if data.bpp() != 32 {
|
||||
return Err(Error::new(EINVAL));
|
||||
}
|
||||
let pixel_format = match data.depth() {
|
||||
24 => DrmFourcc::Xrgb8888,
|
||||
32 => DrmFourcc::Argb8888,
|
||||
_ => return Err(Error::new(EINVAL)),
|
||||
};
|
||||
|
||||
let fb = adapter.create_framebuffer(buffer);
|
||||
|
||||
let id = objects.add_framebuffer(objects::KmsFramebuffer {
|
||||
width: data.width(),
|
||||
height: data.height(),
|
||||
pixel_format,
|
||||
pitch: data.pitch(),
|
||||
buffer: buffer.clone(),
|
||||
driver_data: fb,
|
||||
});
|
||||
|
||||
data.set_fb_id(id.0);
|
||||
|
||||
Ok(0)
|
||||
ipc::MODE_ADD_FB => ipc::DrmModeFbCmd::with(payload, |data| {
|
||||
framebuffer::mode_add_fb(adapter, objects, handle, data)
|
||||
}),
|
||||
ipc::MODE_RM_FB => ipc::StandinForUint::with(payload, |data| {
|
||||
let fb_id = KmsObjectId(data.inner());
|
||||
objects.remove_framebuffer(fb_id)?;
|
||||
|
||||
// Disable planes that use this framebuffer.
|
||||
for (vt, vt_data) in vts {
|
||||
for (plane_idx, plane_state) in vt_data.plane_state.iter_mut().enumerate() {
|
||||
if plane_state.fb_id != Some(fb_id) {
|
||||
continue;
|
||||
}
|
||||
plane_state.fb_id = None;
|
||||
|
||||
if *vt != active_vt {
|
||||
continue;
|
||||
}
|
||||
let plane = objects.planes().nth(plane_idx).unwrap();
|
||||
adapter
|
||||
.set_plane(
|
||||
&objects,
|
||||
plane,
|
||||
plane_state.clone(),
|
||||
Damage {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 0,
|
||||
height: 0,
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
Ok(0)
|
||||
framebuffer::mode_rm_fb(adapter, objects, active_vt, vts, data)
|
||||
}),
|
||||
ipc::MODE_DIRTYFB => ipc::DrmModeFbDirtyCmd::with(payload, |data| {
|
||||
let fb = objects.get_framebuffer(KmsObjectId(data.fb_id()))?;
|
||||
|
||||
let damage = data
|
||||
.clips_ptr()
|
||||
.iter()
|
||||
.map(|rect| Damage {
|
||||
x: u32::from(rect.x1),
|
||||
y: u32::from(rect.y1),
|
||||
width: u32::from(rect.x2 - rect.x1),
|
||||
height: u32::from(rect.y2 - rect.y1),
|
||||
})
|
||||
.reduce(Damage::merge)
|
||||
.unwrap_or(Damage {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: fb.width,
|
||||
height: fb.height,
|
||||
});
|
||||
|
||||
if handle.vt == active_vt {
|
||||
for plane in objects.planes() {
|
||||
let state = plane.lock().unwrap().state.clone();
|
||||
if state.fb_id == Some(KmsObjectId(data.fb_id())) {
|
||||
adapter.set_plane(&objects, plane, state, damage)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(0)
|
||||
framebuffer::mode_dirtyfb(adapter, objects, active_vt, handle, data)
|
||||
}),
|
||||
ipc::MODE_CREATE_DUMB => ipc::DrmModeCreateDumb::with(payload, |mut data| {
|
||||
if data.bpp() != 32 || data.flags() != 0 {
|
||||
@@ -548,29 +447,8 @@ pub(crate) fn call_ioctl<T: GraphicsAdapter>(
|
||||
data.set_format_type_ptr(&[DrmFourcc::Argb8888 as u32]);
|
||||
Ok(0)
|
||||
}),
|
||||
ipc::MODE_ADD_FB2 => ipc::DrmModeFbCmd2::with(payload, |mut data| {
|
||||
// FIXME handle multi-plane framebuffers
|
||||
|
||||
let buffer = handle
|
||||
.buffers
|
||||
.get(&data.handles()[0])
|
||||
.ok_or(Error::new(EINVAL))?;
|
||||
|
||||
let fb = adapter.create_framebuffer(buffer);
|
||||
|
||||
let id = objects.add_framebuffer(objects::KmsFramebuffer {
|
||||
width: data.width(),
|
||||
height: data.height(),
|
||||
pixel_format: DrmFourcc::try_from(data.pixel_format())
|
||||
.map_err(|_| Error::new(EINVAL))?,
|
||||
pitch: data.pitches()[0],
|
||||
buffer: buffer.clone(),
|
||||
driver_data: fb,
|
||||
});
|
||||
|
||||
data.set_fb_id(id.0);
|
||||
|
||||
Ok(0)
|
||||
ipc::MODE_ADD_FB2 => ipc::DrmModeFbCmd2::with(payload, |data| {
|
||||
framebuffer::mode_add_fb2(adapter, objects, handle, data)
|
||||
}),
|
||||
ipc::MODE_OBJ_GET_PROPERTIES => ipc::DrmModeObjGetProperties::with(payload, |mut data| {
|
||||
let (props, prop_vals) =
|
||||
@@ -609,20 +487,8 @@ pub(crate) fn call_ioctl<T: GraphicsAdapter>(
|
||||
|
||||
Ok(0)
|
||||
}),
|
||||
ipc::MODE_GET_FB2 => ipc::DrmModeFbCmd2::with(payload, |mut data| {
|
||||
let fb = objects.get_framebuffer(KmsObjectId(data.fb_id()))?;
|
||||
|
||||
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([handle.next_id, 0, 0, 0]);
|
||||
data.set_pitches([fb.pitch, 0, 0, 0]);
|
||||
data.set_offsets([0; 4]);
|
||||
data.set_modifier([0; 4]);
|
||||
Ok(0)
|
||||
ipc::MODE_GET_FB2 => ipc::DrmModeFbCmd2::with(payload, |data| {
|
||||
framebuffer::mode_get_fb2(objects, handle, data)
|
||||
}),
|
||||
_ => return Err(Error::new(EINVAL)),
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user