diff --git a/drivers/graphics/bgad/src/main.rs b/drivers/graphics/bgad/src/main.rs index 65adf44b11..266c430c74 100644 --- a/drivers/graphics/bgad/src/main.rs +++ b/drivers/graphics/bgad/src/main.rs @@ -48,8 +48,6 @@ fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> ! { display: ProducerHandle::new().ok(), }; - scheme.update_size(); - register_sync_scheme(&socket, "bga", &mut scheme).expect("bgad: failed to register bga scheme"); daemon.ready(); diff --git a/drivers/graphics/bgad/src/scheme.rs b/drivers/graphics/bgad/src/scheme.rs index 80cdc957cc..2401fcf6de 100644 --- a/drivers/graphics/bgad/src/scheme.rs +++ b/drivers/graphics/bgad/src/scheme.rs @@ -13,20 +13,6 @@ pub struct BgaScheme { pub display: Option, } -impl BgaScheme { - pub fn update_size(&mut self) { - if let Some(ref mut display) = self.display { - let _ = display.write_event( - orbclient::ResizeEvent { - width: self.bga.width() as u32, - height: self.bga.height() as u32, - } - .to_event(), - ); - } - } -} - const SCHEME_ROOT_ID: usize = 1; impl SchemeSync for BgaScheme { @@ -98,8 +84,6 @@ impl SchemeSync for BgaScheme { self.bga.set_size(width, height); - self.update_size(); - Ok(buf.len()) } diff --git a/drivers/graphics/driver-graphics/src/lib.rs b/drivers/graphics/driver-graphics/src/lib.rs index 22db654381..e979981f90 100644 --- a/drivers/graphics/driver-graphics/src/lib.rs +++ b/drivers/graphics/driver-graphics/src/lib.rs @@ -292,10 +292,6 @@ impl GraphicsScheme { .handle_cursor(&vt_state.cursor_plane, true); } } - - VtEventKind::Resize => { - log::warn!("driver-graphics: resize is not implemented yet") - } } } } diff --git a/drivers/graphics/ihdgd/src/device/mod.rs b/drivers/graphics/ihdgd/src/device/mod.rs index d04e394358..92ecd65ce0 100644 --- a/drivers/graphics/ihdgd/src/device/mod.rs +++ b/drivers/graphics/ihdgd/src/device/mod.rs @@ -25,7 +25,6 @@ use self::pipe::*; mod power; use self::power::*; mod scheme; -use self::scheme::*; mod transcoder; use self::transcoder::*; @@ -433,40 +432,10 @@ impl Device { for pipe in self.pipes.iter() { for plane in pipe.planes.iter() { if plane.ctl.readf(PLANE_CTL_ENABLE) { - let buf_cfg = plane.buf_cfg.read(); - let buffer_start = buf_cfg & 0x7FF; - let buffer_end = (buf_cfg >> 16) & 0x7FF; - self.alloc_buffers - .allocate_exact_range(buffer_start..(buffer_end + 1)) - .unwrap_or_else(|err| { - panic!( - "failed to allocate pre-existing buffer blocks {} to {}: {:?}", - buffer_start, buffer_end, err - ); - }); + plane.fetch_modeset(&mut self.alloc_buffers); - let size = plane.size.read(); - let width = (size & 0xFFFF) + 1; - let height = ((size >> 16) & 0xFFFF) + 1; - let stride_16 = plane.stride.read() & 0x7FF; - //TODO: this will be wrong for tiled planes - let stride = stride_16 * 16; - let surf = plane.surf.read() & 0xFFFFF000; - //TODO: read bits per pixel - let surf_size = (stride * height * 4).next_multiple_of(4096); - self.alloc_surfaces.allocate_exact_range(surf .. (surf + surf_size)).unwrap_or_else(|err| { - panic!("failed to allocate pre-existing surface at 0x{:x} of size {}: {:?}", surf, surf_size, err); - }); - - self.framebuffers.push(unsafe { - DeviceFb::new( - (self.gm.virt + surf as usize) as *mut u32, - width as usize, - height as usize, - stride as usize, - false, - ) - }); + self.framebuffers + .push(plane.fetch_framebuffer(&self.gm, &mut self.alloc_surfaces)); } } } @@ -747,73 +716,15 @@ impl Device { // Configure and enable planes //TODO: THIS IS HACKY if let Some(plane) = pipe.planes.first_mut() { - //TODO: enable DBUF if more buffers needed - //TODO: more blocks would mean better power usage - // Minimum is 8 blocks for linear planes, 160 blocks is recommended for pre-OS init - let buffer_size = 160; - let buffer = self - .alloc_buffers - .allocate_range(buffer_size) - .map_err(|err| { - log::warn!( - "failed to allocate {} buffer blocks: {:?}", - buffer_size, - err - ); - Error::new(EIO) - })?; - plane.buf_cfg.write(buffer.start | (buffer.end << 16)); - let width = timing.horizontal_active_pixels as u32; let height = timing.vertical_active_lines as u32; - plane.size.write((width - 1) | ((height - 1) << 16)); - //TODO: documentation on this is not great - let stride_16 = (width + 15) / 16; - plane.stride.write(stride_16); - let stride = stride_16 * 16; + let fb = DeviceFb::alloc(&self.gm, &mut self.alloc_surfaces, width, height)?; - //TODO: how is memory allocated for PLANE_SURF? - let surf_size = (stride * height * 4).next_multiple_of(4096); - let surf = self - .alloc_surfaces - .allocate_range(surf_size) - .map_err(|err| { - log::warn!( - "failed to allocate surface of size {}: {:?}", - surf_size, - err - ); - Error::new(EIO) - })?; - plane.surf.write(surf.start); + plane.modeset(&mut self.alloc_buffers)?; + plane.set_framebuffer(&fb); - //TODO: correct watermark calculation - plane.wm[0].write(PLANE_WM_ENABLE | (2 << PLANE_WM_LINES_SHIFT) | buffer_size); - for i in 1..plane.wm.len() { - plane.wm[i].writef(PLANE_WM_ENABLE, false); - } - plane.wm_trans.writef(PLANE_WM_ENABLE, false); - - self.framebuffers.push(unsafe { - DeviceFb::new( - (self.gm.virt + surf.start as usize) as *mut u32, - width as usize, - height as usize, - stride as usize, - true, - ) - }); - - // Disable gamma - if let Some(color_ctl) = &mut plane.color_ctl { - color_ctl.write(plane.color_ctl_gamma_disable); - } - - //TODO: more PLANE_CTL bits - plane - .ctl - .write(PLANE_CTL_ENABLE | plane.ctl_source_rgb_8888); + self.framebuffers.push(fb); } //TODO: VGA and panel fitter steps? diff --git a/drivers/graphics/ihdgd/src/device/pipe.rs b/drivers/graphics/ihdgd/src/device/pipe.rs index 71e8128b4c..4ac2395c71 100644 --- a/drivers/graphics/ihdgd/src/device/pipe.rs +++ b/drivers/graphics/ihdgd/src/device/pipe.rs @@ -1,5 +1,9 @@ +use std::ptr; + use common::io::{Io, MmioPtr}; +use range_alloc::RangeAllocator; use syscall::error::Result; +use syscall::{Error, EIO}; use super::MmioRegion; @@ -8,6 +12,63 @@ pub const PLANE_CTL_ENABLE: u32 = 1 << 31; pub const PLANE_WM_ENABLE: u32 = 1 << 31; pub const PLANE_WM_LINES_SHIFT: u32 = 14; +#[derive(Debug)] +pub struct DeviceFb { + pub onscreen: *mut [u32], + pub surf: u32, + pub width: u32, + pub height: u32, + pub stride: u32, +} + +impl DeviceFb { + pub unsafe fn new( + gm: &MmioRegion, + surf: u32, + width: u32, + height: u32, + stride: u32, + clear: bool, + ) -> Self { + let virt = (gm.virt + surf as usize) as *mut u32; + let onscreen = ptr::slice_from_raw_parts_mut(virt, (stride * height) as usize); + if clear { + (&mut *onscreen).fill(0); + } + Self { + onscreen, + surf, + width, + height, + stride, + } + } + + pub fn alloc( + gm: &MmioRegion, + alloc_surfaces: &mut RangeAllocator, + width: u32, + height: u32, + ) -> syscall::Result { + //TODO: documentation on this is not great + let stride_16 = (width + 15) / 16; + let stride = stride_16 * 16; + + //TODO: how is memory allocated for PLANE_SURF? + let surf_size = (stride * height * 4).next_multiple_of(4096); + let surf = alloc_surfaces.allocate_range(surf_size).map_err(|err| { + log::warn!( + "failed to allocate surface of size {}: {:?}", + surf_size, + err + ); + Error::new(EIO) + })?; + + Ok(unsafe { DeviceFb::new(gm, surf.start, width, height, stride, true) }) + } +} + pub struct Plane { pub name: &'static str, pub index: usize, @@ -27,6 +88,90 @@ pub struct Plane { } impl Plane { + pub fn fetch_modeset(&self, alloc_buffers: &mut RangeAllocator) { + let buf_cfg = self.buf_cfg.read(); + let buffer_start = buf_cfg & 0x7FF; + let buffer_end = (buf_cfg >> 16) & 0x7FF; + alloc_buffers + .allocate_exact_range(buffer_start..(buffer_end + 1)) + .unwrap_or_else(|err| { + panic!( + "failed to allocate pre-existing buffer blocks {} to {}: {:?}", + buffer_start, buffer_end, err + ); + }); + } + + pub fn modeset(&mut self, alloc_buffers: &mut RangeAllocator) -> syscall::Result<()> { + // FIXME handle runtime buffer reconfiguration + //TODO: enable DBUF if more buffers needed + //TODO: more blocks would mean better power usage + // Minimum is 8 blocks for linear planes, 160 blocks is recommended for pre-OS init + let buffer_size = 160; + let buffer = alloc_buffers.allocate_range(buffer_size).map_err(|err| { + log::warn!( + "failed to allocate {} buffer blocks: {:?}", + buffer_size, + err + ); + Error::new(EIO) + })?; + self.buf_cfg.write(buffer.start | (buffer.end << 16)); + + //TODO: correct watermark calculation + self.wm[0].write(PLANE_WM_ENABLE | (2 << PLANE_WM_LINES_SHIFT) | buffer.len() as u32); + for i in 1..self.wm.len() { + self.wm[i].writef(PLANE_WM_ENABLE, false); + } + self.wm_trans.writef(PLANE_WM_ENABLE, false); + + Ok(()) + } + + pub fn fetch_framebuffer( + &self, + gm: &MmioRegion, + alloc_surfaces: &mut RangeAllocator, + ) -> DeviceFb { + let size = self.size.read(); + let width = (size & 0xFFFF) + 1; + let height = ((size >> 16) & 0xFFFF) + 1; + let stride_16 = self.stride.read() & 0x7FF; + //TODO: this will be wrong for tiled planes + let stride = stride_16 * 16; + let surf = self.surf.read() & 0xFFFFF000; + //TODO: read bits per pixel + let surf_size = (stride * height * 4).next_multiple_of(4096); + alloc_surfaces + .allocate_exact_range(surf..(surf + surf_size)) + .unwrap_or_else(|err| { + panic!( + "failed to allocate pre-existing surface at 0x{:x} of size {}: {:?}", + surf, surf_size, err + ); + }); + + unsafe { DeviceFb::new(gm, surf, width, height, stride, true) } + } + + pub fn set_framebuffer(&mut self, fb: &DeviceFb) { + //TODO: documentation on this is not great + let stride_16 = fb.stride / 16; + + self.size.write((fb.width - 1) | ((fb.height - 1) << 16)); + self.stride.write(stride_16); + + self.surf.write(fb.surf); + + // Disable gamma + if let Some(color_ctl) = &mut self.color_ctl { + color_ctl.write(self.color_ctl_gamma_disable); + } + + //TODO: more PLANE_CTL bits + self.ctl.write(PLANE_CTL_ENABLE | self.ctl_source_rgb_8888); + } + pub fn dump(&self) { eprint!("Plane {}", self.name); eprint!(" buf_cfg {:08X}", self.buf_cfg.read()); diff --git a/drivers/graphics/ihdgd/src/device/scheme.rs b/drivers/graphics/ihdgd/src/device/scheme.rs index b86d8ffcb8..629486eca3 100644 --- a/drivers/graphics/ihdgd/src/device/scheme.rs +++ b/drivers/graphics/ihdgd/src/device/scheme.rs @@ -11,6 +11,7 @@ use driver_graphics::{Buffer, CursorPlane, Damage, GraphicsAdapter}; use drm_sys::{DRM_CAP_DUMB_BUFFER, DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT}; use syscall::{error::EINVAL, PAGE_SIZE}; +use super::pipe::DeviceFb; use super::Device; #[derive(Debug)] @@ -114,9 +115,9 @@ impl GraphicsAdapter for Device { for row in 0..framebuffer.height { unsafe { ptr::write_bytes( - onscreen_ptr.add(row * framebuffer.stride), + onscreen_ptr.add((row * framebuffer.stride) as usize), 0, - framebuffer.width, + framebuffer.width as usize, ); } } @@ -135,34 +136,6 @@ impl GraphicsAdapter for Device { } } -pub struct DeviceFb { - pub onscreen: *mut [u32], - pub width: usize, - pub height: usize, - pub stride: usize, -} - -impl DeviceFb { - pub unsafe fn new( - virt: *mut u32, - width: usize, - height: usize, - stride: usize, - clear: bool, - ) -> Self { - let onscreen = ptr::slice_from_raw_parts_mut(virt, stride * height); - if clear { - (&mut *onscreen).fill(0); - } - Self { - onscreen, - width, - height, - stride, - } - } -} - #[derive(Debug)] pub struct DumbFb { width: usize, @@ -227,7 +200,7 @@ impl DumbFb { unsafe { ptr::copy( offscreen_ptr.add(row * self.width + start_x), - onscreen_ptr.add(row * framebuffer.stride + start_x), + onscreen_ptr.add(row * framebuffer.stride as usize + start_x), w, ); } diff --git a/drivers/inputd/src/lib.rs b/drivers/inputd/src/lib.rs index c2015ae646..68fdfc8639 100644 --- a/drivers/inputd/src/lib.rs +++ b/drivers/inputd/src/lib.rs @@ -165,7 +165,7 @@ impl DisplayHandle { pub fn read_vt_event(&mut self) -> io::Result> { let mut event = VtEvent { - kind: VtEventKind::Resize, + kind: VtEventKind::Activate, vt: usize::MAX, width: u32::MAX, height: u32::MAX, @@ -212,7 +212,6 @@ impl ControlHandle { #[repr(usize)] pub enum VtEventKind { Activate, - Resize, } #[derive(Debug)] diff --git a/drivers/inputd/src/main.rs b/drivers/inputd/src/main.rs index f5501137a1..f2dcfefa22 100644 --- a/drivers/inputd/src/main.rs +++ b/drivers/inputd/src/main.rs @@ -443,33 +443,6 @@ impl SchemeSync for InputScheme { } }, - EventOption::Resize(resize_event) => { - for handle in self.handles.values_mut() { - match handle { - Handle::Display { - pending, - notified, - device, - .. - } => { - if self.display.as_ref() == Some(device) { - pending.push(VtEvent { - kind: VtEventKind::Resize, - vt: self.active_vt.unwrap(), - width: resize_event.width, - height: resize_event.height, - - // TODO(andypython): Figure out how to get the stride. - stride: resize_event.width, - }); - *notified = false; - } - } - _ => continue, - } - } - } - _ => continue, }