diff --git a/Cargo.lock b/Cargo.lock index 855971a8df..8ae50305d6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -593,10 +593,10 @@ dependencies = [ "common", "drm-sys", "edid", - "graphics-ipc", "inputd", "libredox", "log", + "redox-ioctl", "redox-scheme", "redox_syscall 0.7.3", ] @@ -932,13 +932,7 @@ dependencies = [ name = "graphics-ipc" version = "0.1.0" dependencies = [ - "common", "drm", - "libredox", - "log", - "plain", - "redox-ioctl", - "redox_syscall 0.7.3", ] [[package]] @@ -1088,7 +1082,6 @@ dependencies = [ "drm-sys", "edid", "embedded-hal", - "graphics-ipc", "libredox", "log", "nb 1.1.0", @@ -2514,7 +2507,6 @@ dependencies = [ "daemon", "driver-graphics", "drm-sys", - "graphics-ipc", "libredox", "orbclient", "ransid", @@ -2569,7 +2561,6 @@ dependencies = [ "driver-graphics", "drm-sys", "futures", - "graphics-ipc", "libredox", "log", "orbclient", diff --git a/drivers/graphics/console-draw/src/lib.rs b/drivers/graphics/console-draw/src/lib.rs index c066a622c9..6c0366c4b6 100644 --- a/drivers/graphics/console-draw/src/lib.rs +++ b/drivers/graphics/console-draw/src/lib.rs @@ -7,9 +7,49 @@ use std::{cmp, io, mem, ptr}; use drm::buffer::{Buffer, DrmFourcc}; use drm::control::dumbbuffer::{DumbBuffer, DumbMapping}; use drm::control::{framebuffer, ClipRect, Device}; -use graphics_ipc::v2::{Damage, V2GraphicsHandle}; +use graphics_ipc::V2GraphicsHandle; use orbclient::FONT; +#[derive(Debug, Copy, Clone)] +#[repr(C, packed)] +pub struct Damage { + pub x: u32, + pub y: u32, + pub width: u32, + pub height: u32, +} + +impl Damage { + pub const NONE: Self = Damage { + x: 0, + y: 0, + width: 0, + height: 0, + }; + + pub fn merge(self, other: Self) -> Self { + if self.width == 0 || self.height == 0 { + return other; + } + + if other.width == 0 || other.height == 0 { + return self; + } + + let x = cmp::min(self.x, other.x); + let y = cmp::min(self.y, other.y); + let x2 = cmp::max(self.x + self.width, other.x + other.width); + let y2 = cmp::max(self.y + self.height, other.y + other.height); + + Damage { + x, + y, + width: x2 - x, + height: y2 - y, + } + } +} + pub struct V2DisplayMap { pub display_handle: V2GraphicsHandle, fb: framebuffer::Handle, diff --git a/drivers/graphics/driver-graphics/Cargo.toml b/drivers/graphics/driver-graphics/Cargo.toml index ff70a9c8c5..a830c4f840 100644 --- a/drivers/graphics/driver-graphics/Cargo.toml +++ b/drivers/graphics/driver-graphics/Cargo.toml @@ -9,12 +9,12 @@ drm-sys.workspace = true #TODO: edid is abandoned, fork it an maintain? edid = "0.3.0" log.workspace = true +redox-ioctl.workspace = true redox-scheme.workspace = true redox_syscall.workspace = true libredox.workspace = true common = { path = "../../common" } -graphics-ipc = { path = "../graphics-ipc" } inputd = { path = "../../inputd" } [lints] diff --git a/drivers/graphics/driver-graphics/src/lib.rs b/drivers/graphics/driver-graphics/src/lib.rs index 1071341352..40d322431d 100644 --- a/drivers/graphics/driver-graphics/src/lib.rs +++ b/drivers/graphics/driver-graphics/src/lib.rs @@ -1,15 +1,13 @@ #![feature(macro_metavar_expr)] -#![feature(slice_as_array)] use std::collections::{BTreeMap, HashMap}; use std::ffi::c_char; use std::fmt::Debug; use std::fs::File; use std::io::{self, Write}; -use std::mem; -use std::mem::transmute; use std::os::fd::BorrowedFd; use std::sync::{Arc, Mutex}; +use std::{cmp, mem}; use drm_sys::{ drm_mode_modeinfo, drm_mode_property_enum, DRM_MODE_CURSOR_BO, DRM_MODE_CURSOR_MOVE, @@ -17,7 +15,6 @@ use drm_sys::{ DRM_MODE_PROP_IMMUTABLE, DRM_MODE_PROP_OBJECT, DRM_MODE_PROP_RANGE, DRM_MODE_PROP_SIGNED_RANGE, DRM_PROP_NAME_LEN, }; -use graphics_ipc::v2::Damage; use inputd::{DisplayHandle, VtEventKind}; use libredox::Fd; use redox_scheme::scheme::{register_scheme_inner, SchemeState, SchemeSync}; @@ -31,6 +28,56 @@ use crate::kms::properties::KmsPropertyKind; pub mod kms; +#[derive(Debug, Copy, Clone)] +#[repr(C, packed)] +pub struct Damage { + pub x: u32, + pub y: u32, + pub width: u32, + pub height: u32, +} + +impl Damage { + fn merge(self, other: Self) -> Self { + if self.width == 0 || self.height == 0 { + return other; + } + + if other.width == 0 || other.height == 0 { + return self; + } + + let x = cmp::min(self.x, other.x); + let y = cmp::min(self.y, other.y); + let x2 = cmp::max(self.x + self.width, other.x + other.width); + let y2 = cmp::max(self.y + self.height, other.y + other.height); + + Damage { + x, + y, + width: x2 - x, + height: y2 - y, + } + } + + #[must_use] + pub fn clip(mut self, width: u32, height: u32) -> Self { + // Clip damage + let x2 = self.x + self.width; + self.x = cmp::min(self.x, width); + if x2 > width { + self.width = width - self.x; + } + + let y2 = self.y + self.height; + self.y = cmp::min(self.y, height); + if y2 > height { + self.height = height - self.y; + } + self + } +} + pub trait GraphicsAdapter: Sized + Debug { type Connector: Debug; type Crtc: Debug; @@ -425,7 +472,7 @@ impl SchemeSync for GraphicsSchemeInner { metadata: &[u64], _ctx: &CallerCtx, ) -> Result { - use graphics_ipc::v2::ipc; + use redox_ioctl::drm as ipc; const DRM_FORMAT_ARGB8888: u32 = 0x34325241; // 'AR24' fourcc code, for ARGB8888 @@ -953,55 +1000,6 @@ impl SchemeSync for GraphicsSchemeInner { data.set_modifier([0; 4]); Ok(0) }), - ipc::UPDATE_PLANE => { - if payload.len() < size_of::() { - return Err(Error::new(EINVAL)); - } - let payload = unsafe { - transmute::<&mut [u8; size_of::()], &mut ipc::UpdatePlane>( - payload.as_mut_array().unwrap(), - ) - }; - - let display_id = payload.display_id; - let Some(crtc) = self.objects.crtcs().nth(display_id) else { - return Err(Error::new(EINVAL)); - }; - - let fb = if payload.fb_id == 0 { - None - } else { - Some(self.objects.get_framebuffer(KmsObjectId(payload.fb_id))?) - }; - - self.vts.get_mut(vt).unwrap().display_fbs[display_id] = if payload.fb_id == 0 { - None - } else { - Some(KmsObjectId(payload.fb_id)) - }; - - if *vt == self.active_vt { - crtc.lock().unwrap().fb_id = KmsObjectId(payload.fb_id); - - let mode = - fb.map(|fb| KmsConnector::<()>::modeinfo_for_size(fb.width, fb.height)); - - self.adapter.set_crtc( - &self.objects, - crtc, - &[self.objects.connector_ids()[display_id]], - mode, - fb, - payload.damage, - ); - - crtc.lock().unwrap().fb_id = KmsObjectId(payload.fb_id); - crtc.lock().unwrap().target_connectors = - vec![self.objects.connector_ids()[display_id]]; - } - - Ok(size_of::()) - } _ => return Err(Error::new(EINVAL)), }, } diff --git a/drivers/graphics/fbbootlogd/src/scheme.rs b/drivers/graphics/fbbootlogd/src/scheme.rs index b925629c43..1d007bad29 100644 --- a/drivers/graphics/fbbootlogd/src/scheme.rs +++ b/drivers/graphics/fbbootlogd/src/scheme.rs @@ -1,10 +1,10 @@ use std::cmp; use std::collections::VecDeque; -use console_draw::{TextScreen, V2DisplayMap}; +use console_draw::{Damage, TextScreen, V2DisplayMap}; use drm::buffer::Buffer; use drm::control::Device; -use graphics_ipc::v2::{Damage, V2GraphicsHandle}; +use graphics_ipc::V2GraphicsHandle; use inputd::ConsumerHandle; use orbclient::{Event, EventOption}; use redox_scheme::scheme::SchemeSync; diff --git a/drivers/graphics/fbcond/src/display.rs b/drivers/graphics/fbcond/src/display.rs index 480fe20420..7e8a5b7571 100644 --- a/drivers/graphics/fbcond/src/display.rs +++ b/drivers/graphics/fbcond/src/display.rs @@ -1,7 +1,7 @@ -use console_draw::{TextScreen, V2DisplayMap}; +use console_draw::{Damage, TextScreen, V2DisplayMap}; use drm::buffer::Buffer; use drm::control::Device; -use graphics_ipc::v2::{Damage, V2GraphicsHandle}; +use graphics_ipc::V2GraphicsHandle; use inputd::ConsumerHandle; use std::io; diff --git a/drivers/graphics/graphics-ipc/Cargo.toml b/drivers/graphics/graphics-ipc/Cargo.toml index 4628ed43f5..edeb40f80d 100644 --- a/drivers/graphics/graphics-ipc/Cargo.toml +++ b/drivers/graphics/graphics-ipc/Cargo.toml @@ -6,13 +6,6 @@ edition = "2021" [dependencies] drm.workspace = true -log.workspace = true -libredox.workspace = true -plain = "0.2" -redox-ioctl.workspace = true -redox_syscall.workspace = true - -common = { path = "../../common" } [lints] workspace = true diff --git a/drivers/graphics/graphics-ipc/src/common.rs b/drivers/graphics/graphics-ipc/src/common.rs deleted file mode 100644 index ca5dc48392..0000000000 --- a/drivers/graphics/graphics-ipc/src/common.rs +++ /dev/null @@ -1,61 +0,0 @@ -use std::cmp; - -// Keep synced with orbital's SyncRect -// Technically orbital uses i32 rather than u32, but values larger than i32::MAX -// would be a bug anyway. -#[derive(Debug, Copy, Clone)] -#[repr(C, packed)] -pub struct Damage { - pub x: u32, - pub y: u32, - pub width: u32, - pub height: u32, -} - -impl Damage { - pub const NONE: Self = Damage { - x: 0, - y: 0, - width: 0, - height: 0, - }; - - pub fn merge(self, other: Self) -> Self { - if self.width == 0 || self.height == 0 { - return other; - } - - if other.width == 0 || other.height == 0 { - return self; - } - - let x = cmp::min(self.x, other.x); - let y = cmp::min(self.y, other.y); - let x2 = cmp::max(self.x + self.width, other.x + other.width); - let y2 = cmp::max(self.y + self.height, other.y + other.height); - - Damage { - x, - y, - width: x2 - x, - height: y2 - y, - } - } - - #[must_use] - pub fn clip(mut self, width: u32, height: u32) -> Self { - // Clip damage - let x2 = self.x + self.width; - self.x = cmp::min(self.x, width); - if x2 > width { - self.width = width - self.x; - } - - let y2 = self.y + self.height; - self.y = cmp::min(self.y, height); - if y2 > height { - self.height = height - self.y; - } - self - } -} diff --git a/drivers/graphics/graphics-ipc/src/lib.rs b/drivers/graphics/graphics-ipc/src/lib.rs index a27c4421c6..4dd3d2ffac 100644 --- a/drivers/graphics/graphics-ipc/src/lib.rs +++ b/drivers/graphics/graphics-ipc/src/lib.rs @@ -1,4 +1,42 @@ -#![feature(macro_metavar_expr_concat)] +use std::fs::File; +use std::io; +use std::os::fd::{AsFd, BorrowedFd}; -mod common; -pub mod v2; +use drm::control::connector::{self, State}; +use drm::control::Device as _; +use drm::{Device as _, DriverCapability}; + +/// A graphics handle using the v2 graphics API. +/// +/// The v2 graphics API allows creating framebuffers on the fly, using them for page flipping and +/// handles all displays using a single fd. This is basically a subset of the Linux DRM interface +/// with a couple of custom ioctls in the place of the KMS ioctls that are missing. +pub struct V2GraphicsHandle { + file: File, +} + +impl AsFd for V2GraphicsHandle { + fn as_fd(&self) -> BorrowedFd<'_> { + self.file.as_fd() + } +} + +impl drm::Device for V2GraphicsHandle {} +impl drm::control::Device for V2GraphicsHandle {} + +impl V2GraphicsHandle { + pub fn from_file(file: File) -> io::Result { + let handle = V2GraphicsHandle { file }; + assert!(handle.get_driver_capability(DriverCapability::DumbBuffer)? == 1); + Ok(handle) + } + + pub fn first_display(&self) -> io::Result { + for &connector in self.resource_handles().unwrap().connectors() { + if self.get_connector(connector, true)?.state() == State::Connected { + return Ok(connector); + } + } + Err(io::Error::other("no connected display")) + } +} diff --git a/drivers/graphics/graphics-ipc/src/v2.rs b/drivers/graphics/graphics-ipc/src/v2.rs deleted file mode 100644 index 60534b8da4..0000000000 --- a/drivers/graphics/graphics-ipc/src/v2.rs +++ /dev/null @@ -1,76 +0,0 @@ -use std::fs::File; -use std::io; -use std::os::fd::{AsFd, BorrowedFd}; -use std::os::unix::io::AsRawFd; - -use drm::control::connector::{self, State}; -use drm::control::Device as _; -use drm::{Device as _, DriverCapability}; -use syscall::CallFlags; - -pub use crate::common::Damage; - -/// A graphics handle using the v2 graphics API. -/// -/// The v2 graphics API allows creating framebuffers on the fly, using them for page flipping and -/// handles all displays using a single fd. This is basically a subset of the Linux DRM interface -/// with a couple of custom ioctls in the place of the KMS ioctls that are missing. -pub struct V2GraphicsHandle { - file: File, -} - -impl AsFd for V2GraphicsHandle { - fn as_fd(&self) -> BorrowedFd<'_> { - self.file.as_fd() - } -} - -impl drm::Device for V2GraphicsHandle {} -impl drm::control::Device for V2GraphicsHandle {} - -impl V2GraphicsHandle { - pub fn from_file(file: File) -> io::Result { - let handle = V2GraphicsHandle { file }; - assert!(handle.get_driver_capability(DriverCapability::DumbBuffer)? == 1); - Ok(handle) - } - - pub fn first_display(&self) -> io::Result { - for &connector in self.resource_handles().unwrap().connectors() { - if self.get_connector(connector, true)?.state() == State::Connected { - return Ok(connector); - } - } - Err(io::Error::other("no connected display")) - } - - pub fn update_plane(&self, display_id: usize, fb_id: u32, damage: Damage) -> io::Result<()> { - let cmd = ipc::UpdatePlane { - display_id, - fb_id, - damage, - }; - libredox::call::call_wo( - self.file.as_raw_fd() as usize, - unsafe { plain::as_bytes(&cmd) }, - CallFlags::empty(), - &[ipc::UPDATE_PLANE, 0, 0], - )?; - Ok(()) - } -} - -pub mod ipc { - use crate::common::Damage; - - pub use redox_ioctl::drm::*; - - // FIXME replace these with proper drm interfaces and update orbital - pub const UPDATE_PLANE: u64 = 0x12345670; - #[repr(C, packed)] - pub struct UpdatePlane { - pub display_id: usize, - pub fb_id: u32, - pub damage: Damage, - } -} diff --git a/drivers/graphics/ihdgd/Cargo.toml b/drivers/graphics/ihdgd/Cargo.toml index 6cfbd17000..7b9d5778d0 100644 --- a/drivers/graphics/ihdgd/Cargo.toml +++ b/drivers/graphics/ihdgd/Cargo.toml @@ -20,7 +20,6 @@ void = "1.0" common = { path = "../../common" } daemon = { path = "../../../daemon" } driver-graphics = { path = "../driver-graphics" } -graphics-ipc = { path = "../graphics-ipc" } pcid = { path = "../../pcid" } libredox.workspace = true diff --git a/drivers/graphics/ihdgd/src/device/scheme.rs b/drivers/graphics/ihdgd/src/device/scheme.rs index 52cbb218d2..5dd093c421 100644 --- a/drivers/graphics/ihdgd/src/device/scheme.rs +++ b/drivers/graphics/ihdgd/src/device/scheme.rs @@ -8,10 +8,10 @@ use std::sync::Mutex; use driver_graphics::kms::connector::KmsConnectorStatus; use driver_graphics::kms::objects::{self, KmsCrtc, KmsObjectId, KmsObjects}; use driver_graphics::kms::properties::DPMS; -use driver_graphics::{Buffer, CursorPlane, GraphicsAdapter}; -use drm_sys::{drm_mode_modeinfo, DRM_MODE_DPMS_ON}; -use graphics_ipc::v2::ipc::{DRM_CAP_DUMB_BUFFER, DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT}; -use graphics_ipc::v2::Damage; +use driver_graphics::{Buffer, CursorPlane, Damage, GraphicsAdapter}; +use drm_sys::{ + drm_mode_modeinfo, DRM_CAP_DUMB_BUFFER, DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT, DRM_MODE_DPMS_ON, +}; use syscall::{error::EINVAL, PAGE_SIZE}; use super::Device; diff --git a/drivers/graphics/vesad/Cargo.toml b/drivers/graphics/vesad/Cargo.toml index 5c339e29d6..fe5fc64018 100644 --- a/drivers/graphics/vesad/Cargo.toml +++ b/drivers/graphics/vesad/Cargo.toml @@ -14,7 +14,6 @@ redox_event.workspace = true common = { path = "../../common" } daemon = { path = "../../../daemon" } driver-graphics = { path = "../driver-graphics" } -graphics-ipc = { path = "../graphics-ipc" } libredox.workspace = true [features] diff --git a/drivers/graphics/vesad/src/scheme.rs b/drivers/graphics/vesad/src/scheme.rs index 45c828f2ac..d51ac723a8 100644 --- a/drivers/graphics/vesad/src/scheme.rs +++ b/drivers/graphics/vesad/src/scheme.rs @@ -6,10 +6,10 @@ use std::sync::Mutex; use driver_graphics::kms::connector::KmsConnectorStatus; use driver_graphics::kms::objects::{self, KmsCrtc, KmsObjectId, KmsObjects}; use driver_graphics::kms::properties::DPMS; -use driver_graphics::{Buffer, CursorPlane, GraphicsAdapter}; -use drm_sys::{drm_mode_modeinfo, DRM_MODE_DPMS_ON}; -use graphics_ipc::v2::ipc::{DRM_CAP_DUMB_BUFFER, DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT}; -use graphics_ipc::v2::Damage; +use driver_graphics::{Buffer, CursorPlane, Damage, GraphicsAdapter}; +use drm_sys::{ + drm_mode_modeinfo, DRM_CAP_DUMB_BUFFER, DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT, DRM_MODE_DPMS_ON, +}; use syscall::{EINVAL, PAGE_SIZE}; #[derive(Debug)] diff --git a/drivers/graphics/virtio-gpud/Cargo.toml b/drivers/graphics/virtio-gpud/Cargo.toml index 4359756f1f..cd015f7c86 100644 --- a/drivers/graphics/virtio-gpud/Cargo.toml +++ b/drivers/graphics/virtio-gpud/Cargo.toml @@ -15,7 +15,6 @@ anyhow.workspace = true common = { path = "../../common" } daemon = { path = "../../../daemon" } driver-graphics = { path = "../driver-graphics" } -graphics-ipc = { path = "../graphics-ipc" } virtio-core = { path = "../../virtio-core" } pcid = { path = "../../pcid" } diff --git a/drivers/graphics/virtio-gpud/src/scheme.rs b/drivers/graphics/virtio-gpud/src/scheme.rs index 8265846d61..b550f060fa 100644 --- a/drivers/graphics/virtio-gpud/src/scheme.rs +++ b/drivers/graphics/virtio-gpud/src/scheme.rs @@ -5,10 +5,11 @@ use common::{dma::Dma, sgl}; use driver_graphics::kms::connector::KmsConnectorStatus; use driver_graphics::kms::objects::{self, KmsCrtc, KmsObjectId, KmsObjects}; use driver_graphics::kms::properties::{DPMS, EDID}; -use driver_graphics::{Buffer as DrmBuffer, CursorPlane, GraphicsAdapter, GraphicsScheme}; -use drm_sys::{drm_mode_modeinfo, DRM_CAP_CURSOR_HEIGHT, DRM_CAP_CURSOR_WIDTH, DRM_MODE_DPMS_ON}; -use graphics_ipc::v2::ipc::{DRM_CAP_DUMB_BUFFER, DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT}; -use graphics_ipc::v2::Damage; +use driver_graphics::{Buffer as DrmBuffer, CursorPlane, Damage, GraphicsAdapter, GraphicsScheme}; +use drm_sys::{ + drm_mode_modeinfo, DRM_CAP_CURSOR_HEIGHT, DRM_CAP_CURSOR_WIDTH, DRM_CAP_DUMB_BUFFER, + DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT, DRM_MODE_DPMS_ON, +}; use syscall::{EINVAL, PAGE_SIZE};