Merge branch 'graphics_ipc_crate' into 'master'
graphics: Introduce graphics-ipc crate See merge request redox-os/drivers!227
This commit is contained in:
Generated
+15
-1
@@ -326,7 +326,7 @@ dependencies = [
|
||||
name = "console-draw"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"inputd",
|
||||
"graphics-ipc",
|
||||
"orbclient",
|
||||
"ransid",
|
||||
]
|
||||
@@ -401,6 +401,7 @@ name = "driver-graphics"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"common",
|
||||
"graphics-ipc",
|
||||
"inputd",
|
||||
"libredox",
|
||||
"log",
|
||||
@@ -442,6 +443,7 @@ name = "fbbootlogd"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"console-draw",
|
||||
"graphics-ipc",
|
||||
"inputd",
|
||||
"libredox",
|
||||
"orbclient",
|
||||
@@ -457,6 +459,7 @@ name = "fbcond"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"console-draw",
|
||||
"graphics-ipc",
|
||||
"inputd",
|
||||
"libredox",
|
||||
"orbclient",
|
||||
@@ -602,6 +605,15 @@ dependencies = [
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "graphics-ipc"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"common",
|
||||
"libredox",
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.15.1"
|
||||
@@ -1713,6 +1725,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"common",
|
||||
"driver-graphics",
|
||||
"graphics-ipc",
|
||||
"inputd",
|
||||
"libredox",
|
||||
"orbclient",
|
||||
@@ -1768,6 +1781,7 @@ dependencies = [
|
||||
"common",
|
||||
"driver-graphics",
|
||||
"futures",
|
||||
"graphics-ipc",
|
||||
"inputd",
|
||||
"libredox",
|
||||
"log",
|
||||
|
||||
@@ -21,6 +21,7 @@ members = [
|
||||
"graphics/fbbootlogd",
|
||||
"graphics/driver-graphics",
|
||||
"graphics/fbcond",
|
||||
"graphics/graphics-ipc",
|
||||
"graphics/vesad",
|
||||
"graphics/virtio-gpud",
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ edition = "2021"
|
||||
orbclient = "0.3.27"
|
||||
ransid = "0.4"
|
||||
|
||||
inputd = { path = "../../inputd" }
|
||||
graphics-ipc = { path = "../graphics-ipc" }
|
||||
|
||||
[features]
|
||||
default = []
|
||||
|
||||
@@ -4,7 +4,7 @@ use std::collections::{BTreeSet, VecDeque};
|
||||
use std::convert::{TryFrom, TryInto};
|
||||
use std::{cmp, ptr};
|
||||
|
||||
use inputd::Damage;
|
||||
use graphics_ipc::legacy::Damage;
|
||||
use orbclient::FONT;
|
||||
|
||||
pub struct DisplayMap {
|
||||
|
||||
@@ -10,4 +10,5 @@ redox_syscall = "0.5"
|
||||
libredox = "0.1.3"
|
||||
|
||||
common = { path = "../../common" }
|
||||
graphics-ipc = { path = "../graphics-ipc" }
|
||||
inputd = { path = "../../inputd" }
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use std::io;
|
||||
|
||||
use inputd::{Damage, VtEvent, VtEventKind};
|
||||
use graphics_ipc::legacy::Damage;
|
||||
use inputd::{VtEvent, VtEventKind};
|
||||
use libredox::errno::EOPNOTSUPP;
|
||||
use libredox::Fd;
|
||||
use redox_scheme::{RequestKind, Response, Scheme, SignalBehavior, Socket};
|
||||
|
||||
@@ -12,6 +12,7 @@ redox-daemon = "0.1"
|
||||
redox-scheme = { git = "https://gitlab.redox-os.org/redox-os/redox-scheme.git" }
|
||||
|
||||
console-draw = { path = "../console-draw" }
|
||||
graphics-ipc = { path = "../graphics-ipc" }
|
||||
inputd = { path = "../../inputd" }
|
||||
libredox = "0.1.3"
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
use event::{user_data, EventQueue};
|
||||
use inputd::{ConsumerHandle, Damage};
|
||||
use graphics_ipc::legacy::{Damage, LegacyGraphicsHandle};
|
||||
use inputd::ConsumerHandle;
|
||||
use libredox::errno::ESTALE;
|
||||
use libredox::flag;
|
||||
use orbclient::Event;
|
||||
use std::mem;
|
||||
use std::os::fd::BorrowedFd;
|
||||
use std::sync::mpsc::{self, Receiver, Sender};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::{fs::File, io, os::unix::io::AsRawFd, slice};
|
||||
use std::{io, os::unix::io::AsRawFd, slice};
|
||||
|
||||
fn read_to_slice<T: Copy>(
|
||||
file: BorrowedFd,
|
||||
@@ -22,46 +22,17 @@ fn read_to_slice<T: Copy>(
|
||||
}
|
||||
}
|
||||
|
||||
fn display_fd_map(width: usize, height: usize, display_file: File) -> syscall::Result<DisplayMap> {
|
||||
unsafe {
|
||||
let display_ptr = libredox::call::mmap(libredox::call::MmapArgs {
|
||||
fd: display_file.as_raw_fd() as usize,
|
||||
offset: 0,
|
||||
length: (width * height * 4),
|
||||
prot: flag::PROT_READ | flag::PROT_WRITE,
|
||||
flags: flag::MAP_SHARED,
|
||||
addr: core::ptr::null_mut(),
|
||||
})?;
|
||||
let display_slice = slice::from_raw_parts_mut(display_ptr as *mut u32, width * height);
|
||||
Ok(DisplayMap {
|
||||
display_file: Arc::new(display_file),
|
||||
offscreen: display_slice,
|
||||
width,
|
||||
height,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn display_fd_unmap(image: *mut [u32]) {
|
||||
let _ = libredox::call::munmap(image as *mut (), image.len());
|
||||
fn display_fd_map(display_handle: LegacyGraphicsHandle) -> io::Result<DisplayMap> {
|
||||
let display_map = display_handle.map_display()?;
|
||||
Ok(DisplayMap {
|
||||
display_handle: Arc::new(display_handle),
|
||||
inner: display_map,
|
||||
})
|
||||
}
|
||||
|
||||
pub struct DisplayMap {
|
||||
display_file: Arc<File>,
|
||||
pub offscreen: *mut [u32],
|
||||
pub width: usize,
|
||||
pub height: usize,
|
||||
}
|
||||
|
||||
unsafe impl Send for DisplayMap {}
|
||||
unsafe impl Sync for DisplayMap {}
|
||||
|
||||
impl Drop for DisplayMap {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
display_fd_unmap(self.offscreen);
|
||||
}
|
||||
}
|
||||
display_handle: Arc<LegacyGraphicsHandle>,
|
||||
pub inner: graphics_ipc::legacy::DisplayMap,
|
||||
}
|
||||
|
||||
enum DisplayCommand {
|
||||
@@ -77,11 +48,10 @@ impl Display {
|
||||
pub fn open_first_vt() -> io::Result<Self> {
|
||||
let input_handle = ConsumerHandle::for_vt(1)?;
|
||||
|
||||
let (display_file, width, height) = Self::open_display(&input_handle)?;
|
||||
let display_handle = LegacyGraphicsHandle::from_file(input_handle.open_display()?)?;
|
||||
|
||||
let map = Arc::new(Mutex::new(
|
||||
display_fd_map(width, height, display_file)
|
||||
.unwrap_or_else(|e| panic!("failed to map display: {e}")),
|
||||
display_fd_map(display_handle).unwrap_or_else(|e| panic!("failed to map display: {e}")),
|
||||
));
|
||||
|
||||
let map_clone = map.clone();
|
||||
@@ -98,34 +68,6 @@ impl Display {
|
||||
Ok(Self { cmd_tx, map })
|
||||
}
|
||||
|
||||
fn open_display(input_handle: &ConsumerHandle) -> io::Result<(File, usize, usize)> {
|
||||
let display_file = input_handle.open_display()?;
|
||||
|
||||
let mut buf: [u8; 4096] = [0; 4096];
|
||||
let count = libredox::call::fpath(display_file.as_raw_fd() as usize, &mut buf)
|
||||
.unwrap_or_else(|e| {
|
||||
panic!("Could not read display path with fpath(): {e}");
|
||||
});
|
||||
|
||||
let url =
|
||||
String::from_utf8(Vec::from(&buf[..count])).expect("Could not create Utf8 Url String");
|
||||
let path = url.split(':').nth(1).expect("Could not get path from url");
|
||||
|
||||
let mut path_parts = path.split('/').skip(1);
|
||||
let width = path_parts
|
||||
.next()
|
||||
.unwrap_or("")
|
||||
.parse::<usize>()
|
||||
.unwrap_or(0);
|
||||
let height = path_parts
|
||||
.next()
|
||||
.unwrap_or("")
|
||||
.parse::<usize>()
|
||||
.unwrap_or(0);
|
||||
|
||||
Ok((display_file, width, height))
|
||||
}
|
||||
|
||||
fn handle_input_events(map: Arc<Mutex<DisplayMap>>, input_handle: ConsumerHandle) {
|
||||
let event_queue = EventQueue::new().expect("fbbootlogd: failed to create event queue");
|
||||
|
||||
@@ -151,10 +93,11 @@ impl Display {
|
||||
Err(err) if err.errno() == ESTALE => {
|
||||
eprintln!("fbbootlogd: handoff requested");
|
||||
|
||||
let (new_display_file, width, height) =
|
||||
Self::open_display(&input_handle).unwrap();
|
||||
let new_display_handle =
|
||||
LegacyGraphicsHandle::from_file(input_handle.open_display().unwrap())
|
||||
.unwrap();
|
||||
|
||||
match display_fd_map(width, height, new_display_file) {
|
||||
match display_fd_map(new_display_handle) {
|
||||
Ok(ok) => {
|
||||
*map.lock().unwrap() = ok;
|
||||
|
||||
@@ -177,19 +120,12 @@ impl Display {
|
||||
fn handle_sync_rect(map: Arc<Mutex<DisplayMap>>, cmd_rx: Receiver<DisplayCommand>) {
|
||||
while let Ok(cmd) = cmd_rx.recv() {
|
||||
match cmd {
|
||||
DisplayCommand::SyncRects(sync_rects) => unsafe {
|
||||
DisplayCommand::SyncRects(sync_rects) => {
|
||||
// We may not hold this lock across the write call to avoid deadlocking if the
|
||||
// graphics driver tries to write to the bootlog.
|
||||
let display_file = map.lock().unwrap().display_file.clone();
|
||||
libredox::call::write(
|
||||
display_file.as_raw_fd() as usize,
|
||||
slice::from_raw_parts(
|
||||
sync_rects.as_ptr() as *const u8,
|
||||
sync_rects.len() * mem::size_of::<Damage>(),
|
||||
),
|
||||
)
|
||||
.unwrap();
|
||||
},
|
||||
let display_handle = map.lock().unwrap().display_handle.clone();
|
||||
display_handle.sync_rects(&sync_rects).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,12 +22,12 @@ impl TextScreen {
|
||||
|
||||
impl TextScreen {
|
||||
pub fn write(&mut self, buf: &[u8]) -> Result<usize> {
|
||||
let map = self.display.map.lock().unwrap();
|
||||
let mut map = self.display.map.lock().unwrap();
|
||||
let damage = self.inner.write(
|
||||
&mut console_draw::DisplayMap {
|
||||
offscreen: map.offscreen,
|
||||
width: map.width,
|
||||
height: map.height,
|
||||
offscreen: map.inner.ptr_mut(),
|
||||
width: map.inner.width(),
|
||||
height: map.inner.height(),
|
||||
},
|
||||
buf,
|
||||
&mut VecDeque::new(),
|
||||
|
||||
@@ -12,6 +12,7 @@ redox-daemon = "0.1"
|
||||
redox-scheme = { git = "https://gitlab.redox-os.org/redox-os/redox-scheme.git" }
|
||||
|
||||
console-draw = { path = "../console-draw" }
|
||||
graphics-ipc = { path = "../graphics-ipc" }
|
||||
inputd = { path = "../../inputd" }
|
||||
libredox = "0.1.3"
|
||||
|
||||
|
||||
+25
-113
@@ -1,57 +1,27 @@
|
||||
use inputd::{ConsumerHandle, Damage};
|
||||
use libredox::flag;
|
||||
use std::fs::File;
|
||||
use std::os::unix::io::AsRawFd;
|
||||
use std::{io, mem, ptr, slice};
|
||||
|
||||
fn display_fd_map(
|
||||
width: usize,
|
||||
height: usize,
|
||||
display_file: &mut File,
|
||||
) -> syscall::Result<*mut [u32]> {
|
||||
unsafe {
|
||||
let display_ptr = libredox::call::mmap(libredox::call::MmapArgs {
|
||||
fd: display_file.as_raw_fd() as usize,
|
||||
offset: 0,
|
||||
length: (width * height * 4),
|
||||
prot: flag::PROT_READ | flag::PROT_WRITE,
|
||||
flags: flag::MAP_SHARED,
|
||||
addr: core::ptr::null_mut(),
|
||||
})?;
|
||||
Ok(ptr::slice_from_raw_parts_mut(
|
||||
display_ptr as *mut u32,
|
||||
width * height,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn display_fd_unmap(image: *mut [u32]) {
|
||||
let _ = libredox::call::munmap(image as *mut (), image.len());
|
||||
}
|
||||
use graphics_ipc::legacy::{Damage, DisplayMap, LegacyGraphicsHandle};
|
||||
use inputd::ConsumerHandle;
|
||||
use std::io;
|
||||
|
||||
pub struct Display {
|
||||
pub input_handle: ConsumerHandle,
|
||||
pub display_file: File,
|
||||
pub offscreen: *mut [u32],
|
||||
pub width: usize,
|
||||
pub height: usize,
|
||||
pub display_handle: LegacyGraphicsHandle,
|
||||
pub map: DisplayMap,
|
||||
}
|
||||
|
||||
impl Display {
|
||||
pub fn open_vt(vt: usize) -> io::Result<Self> {
|
||||
let input_handle = ConsumerHandle::for_vt(vt)?;
|
||||
|
||||
let (mut display_file, width, height) = Self::open_display(&input_handle)?;
|
||||
let display_handle = Self::open_display(&input_handle)?;
|
||||
|
||||
let offscreen = display_fd_map(width, height, &mut display_file)
|
||||
let map = display_handle
|
||||
.map_display()
|
||||
.unwrap_or_else(|e| panic!("failed to map display for VT #{vt}: {e}"));
|
||||
|
||||
Ok(Self {
|
||||
input_handle,
|
||||
display_file,
|
||||
offscreen,
|
||||
width,
|
||||
height,
|
||||
display_handle,
|
||||
map,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -59,92 +29,34 @@ impl Display {
|
||||
pub fn reopen_for_handoff(&mut self) {
|
||||
eprintln!("fbcond: Performing handoff");
|
||||
|
||||
let (mut new_display_file, width, height) = Self::open_display(&self.input_handle).unwrap();
|
||||
let new_display_handle = Self::open_display(&self.input_handle).unwrap();
|
||||
|
||||
eprintln!("fbcond: Opened new display with size {width}x{height}");
|
||||
eprintln!("fbcond: Opened new display");
|
||||
|
||||
match display_fd_map(width, height, &mut new_display_file) {
|
||||
Ok(offscreen) => {
|
||||
unsafe {
|
||||
display_fd_unmap(self.offscreen);
|
||||
}
|
||||
match new_display_handle.map_display() {
|
||||
Ok(map) => {
|
||||
self.map = map;
|
||||
self.display_handle = new_display_handle;
|
||||
|
||||
self.offscreen = offscreen;
|
||||
self.width = width;
|
||||
self.height = height;
|
||||
self.display_file = new_display_file;
|
||||
|
||||
eprintln!("fbcond: Mapped new display");
|
||||
eprintln!(
|
||||
"fbcond: Mapped new display with size {}x{}",
|
||||
self.map.width(),
|
||||
self.map.height()
|
||||
);
|
||||
}
|
||||
Err(err) => {
|
||||
eprintln!("failed to resize display to {}x{}: {}", width, height, err);
|
||||
eprintln!("failed to resize display: {}", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn open_display(input_handle: &ConsumerHandle) -> io::Result<(File, usize, usize)> {
|
||||
fn open_display(input_handle: &ConsumerHandle) -> io::Result<LegacyGraphicsHandle> {
|
||||
let display_file = input_handle.open_display()?;
|
||||
|
||||
let mut buf: [u8; 4096] = [0; 4096];
|
||||
let count = libredox::call::fpath(display_file.as_raw_fd() as usize, &mut buf)
|
||||
.unwrap_or_else(|e| {
|
||||
panic!("Could not read display path with fpath(): {e}");
|
||||
});
|
||||
|
||||
let url =
|
||||
String::from_utf8(Vec::from(&buf[..count])).expect("Could not create Utf8 Url String");
|
||||
let path = url.split(':').nth(1).expect("Could not get path from url");
|
||||
|
||||
let mut path_parts = path.split('/').skip(1);
|
||||
let width = path_parts
|
||||
.next()
|
||||
.unwrap_or("")
|
||||
.parse::<usize>()
|
||||
.unwrap_or(0);
|
||||
let height = path_parts
|
||||
.next()
|
||||
.unwrap_or("")
|
||||
.parse::<usize>()
|
||||
.unwrap_or(0);
|
||||
|
||||
Ok((display_file, width, height))
|
||||
}
|
||||
|
||||
pub fn resize(&mut self, width: usize, height: usize) {
|
||||
match display_fd_map(width, height, &mut self.display_file) {
|
||||
Ok(offscreen) => {
|
||||
unsafe {
|
||||
display_fd_unmap(self.offscreen);
|
||||
}
|
||||
|
||||
self.offscreen = offscreen;
|
||||
self.width = width;
|
||||
self.height = height;
|
||||
}
|
||||
Err(err) => {
|
||||
eprintln!("failed to resize display to {}x{}: {}", width, height, err);
|
||||
}
|
||||
}
|
||||
LegacyGraphicsHandle::from_file(display_file)
|
||||
}
|
||||
|
||||
pub fn sync_rects(&mut self, sync_rects: Vec<Damage>) {
|
||||
unsafe {
|
||||
libredox::call::write(
|
||||
self.display_file.as_raw_fd() as usize,
|
||||
slice::from_raw_parts(
|
||||
sync_rects.as_ptr() as *const u8,
|
||||
sync_rects.len() * mem::size_of::<Damage>(),
|
||||
),
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Display {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
display_fd_unmap(self.offscreen);
|
||||
}
|
||||
self.display_handle.sync_rects(&sync_rects).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,12 +60,6 @@ impl FbconScheme {
|
||||
handles: BTreeMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
fn resize(&mut self, width: usize, height: usize, stride: usize) {
|
||||
for console in self.vts.values_mut() {
|
||||
console.resize(width, height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl SchemeBlock for FbconScheme {
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
extern crate ransid;
|
||||
|
||||
use std::collections::VecDeque;
|
||||
use std::convert::TryInto;
|
||||
|
||||
use orbclient::{Event, EventOption};
|
||||
use syscall::error::*;
|
||||
@@ -29,11 +26,6 @@ impl TextScreen {
|
||||
self.display.reopen_for_handoff();
|
||||
}
|
||||
|
||||
pub fn resize(&mut self, width: usize, height: usize) {
|
||||
self.display
|
||||
.resize(width.try_into().unwrap(), height.try_into().unwrap());
|
||||
}
|
||||
|
||||
pub fn input(&mut self, event: &Event) {
|
||||
let mut buf = vec![];
|
||||
|
||||
@@ -130,9 +122,9 @@ impl TextScreen {
|
||||
pub fn write(&mut self, buf: &[u8]) -> Result<usize> {
|
||||
let damage = self.inner.write(
|
||||
&mut console_draw::DisplayMap {
|
||||
offscreen: self.display.offscreen,
|
||||
width: self.display.width,
|
||||
height: self.display.height,
|
||||
offscreen: self.display.map.ptr_mut(),
|
||||
width: self.display.map.width(),
|
||||
height: self.display.map.height(),
|
||||
},
|
||||
buf,
|
||||
&mut self.input,
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
[package]
|
||||
name = "graphics-ipc"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
log = "0.4"
|
||||
libredox = "0.1.3"
|
||||
|
||||
common = { path = "../../common" }
|
||||
@@ -0,0 +1,137 @@
|
||||
use std::fs::File;
|
||||
use std::os::unix::io::AsRawFd;
|
||||
use std::{cmp, io, mem, ptr, slice};
|
||||
|
||||
use libredox::flag;
|
||||
|
||||
/// A graphics handle using the legacy graphics API.
|
||||
///
|
||||
/// The legacy graphics API only allows a single framebuffer for each VT and supports neither page
|
||||
/// flipping nor cursor planes.
|
||||
pub struct LegacyGraphicsHandle {
|
||||
file: File,
|
||||
}
|
||||
|
||||
impl LegacyGraphicsHandle {
|
||||
pub fn from_file(file: File) -> io::Result<Self> {
|
||||
Ok(LegacyGraphicsHandle { file })
|
||||
}
|
||||
|
||||
pub fn map_display(&self) -> io::Result<DisplayMap> {
|
||||
let mut buf: [u8; 4096] = [0; 4096];
|
||||
let count =
|
||||
libredox::call::fpath(self.file.as_raw_fd() as usize, &mut buf).unwrap_or_else(|e| {
|
||||
panic!("Could not read display path with fpath(): {e}");
|
||||
});
|
||||
|
||||
let url =
|
||||
String::from_utf8(Vec::from(&buf[..count])).expect("Could not create Utf8 Url String");
|
||||
let path = url.split(':').nth(1).expect("Could not get path from url");
|
||||
|
||||
let mut path_parts = path.split('/').skip(1);
|
||||
let width = path_parts
|
||||
.next()
|
||||
.unwrap_or("")
|
||||
.parse::<usize>()
|
||||
.unwrap_or(0);
|
||||
let height = path_parts
|
||||
.next()
|
||||
.unwrap_or("")
|
||||
.parse::<usize>()
|
||||
.unwrap_or(0);
|
||||
|
||||
let display_ptr = unsafe {
|
||||
libredox::call::mmap(libredox::call::MmapArgs {
|
||||
fd: self.file.as_raw_fd() as usize,
|
||||
offset: 0,
|
||||
length: (width * height * 4),
|
||||
prot: flag::PROT_READ | flag::PROT_WRITE,
|
||||
flags: flag::MAP_SHARED,
|
||||
addr: core::ptr::null_mut(),
|
||||
})?
|
||||
};
|
||||
let offscreen = ptr::slice_from_raw_parts_mut(display_ptr as *mut u32, width * height);
|
||||
|
||||
Ok(DisplayMap {
|
||||
offscreen,
|
||||
width,
|
||||
height,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn sync_full_screen(&self) -> io::Result<()> {
|
||||
libredox::call::fsync(self.file.as_raw_fd() as usize)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn sync_rects(&self, sync_rects: &[Damage]) -> io::Result<()> {
|
||||
libredox::call::write(self.file.as_raw_fd() as usize, unsafe {
|
||||
slice::from_raw_parts(
|
||||
sync_rects.as_ptr() as *const u8,
|
||||
sync_rects.len() * mem::size_of::<Damage>(),
|
||||
)
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DisplayMap {
|
||||
offscreen: *mut [u32],
|
||||
width: usize,
|
||||
height: usize,
|
||||
}
|
||||
|
||||
impl DisplayMap {
|
||||
pub fn ptr(&self) -> *const [u32] {
|
||||
self.offscreen
|
||||
}
|
||||
|
||||
pub fn ptr_mut(&mut self) -> *mut [u32] {
|
||||
self.offscreen
|
||||
}
|
||||
|
||||
pub fn width(&self) -> usize {
|
||||
self.width
|
||||
}
|
||||
|
||||
pub fn height(&self) -> usize {
|
||||
self.height
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Send for DisplayMap {}
|
||||
unsafe impl Sync for DisplayMap {}
|
||||
|
||||
impl Drop for DisplayMap {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
let _ = libredox::call::munmap(self.offscreen as *mut (), self.offscreen.len());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Keep synced with orbital's SyncRect
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
#[repr(packed)]
|
||||
pub struct Damage {
|
||||
pub x: i32,
|
||||
pub y: i32,
|
||||
pub width: i32,
|
||||
pub height: i32,
|
||||
}
|
||||
|
||||
impl Damage {
|
||||
#[must_use]
|
||||
pub fn clip(mut self, width: i32, height: i32) -> Self {
|
||||
// Clip damage
|
||||
self.x = cmp::min(self.x, width);
|
||||
if self.x + self.width > width {
|
||||
self.width -= cmp::min(self.width, width - self.x);
|
||||
}
|
||||
self.y = cmp::min(self.y, height);
|
||||
if self.y + self.height > height {
|
||||
self.height = cmp::min(self.height, height - self.y);
|
||||
}
|
||||
self
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
pub mod legacy;
|
||||
@@ -12,6 +12,7 @@ redox_event = "0.4.1"
|
||||
|
||||
common = { path = "../../common" }
|
||||
driver-graphics = { path = "../driver-graphics" }
|
||||
graphics-ipc = { path = "../graphics-ipc" }
|
||||
inputd = { path = "../../inputd" }
|
||||
libredox = "0.1.3"
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use driver_graphics::GraphicsAdapter;
|
||||
use graphics_ipc::legacy::Damage;
|
||||
|
||||
use crate::{framebuffer::FrameBuffer, screen::GraphicScreen};
|
||||
|
||||
@@ -36,7 +37,7 @@ impl GraphicsAdapter for FbAdapter {
|
||||
&mut self,
|
||||
display_id: usize,
|
||||
resource: &Self::Resource,
|
||||
damage: Option<&[inputd::Damage]>,
|
||||
damage: Option<&[Damage]>,
|
||||
) {
|
||||
if let Some(damage) = damage {
|
||||
resource.sync(&mut self.framebuffers[display_id], damage)
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::convert::TryInto;
|
||||
use std::ptr::{self, NonNull};
|
||||
|
||||
use driver_graphics::Resource;
|
||||
use inputd::Damage;
|
||||
use graphics_ipc::legacy::Damage;
|
||||
use syscall::PAGE_SIZE;
|
||||
|
||||
use crate::framebuffer::FrameBuffer;
|
||||
|
||||
@@ -12,6 +12,7 @@ anyhow = "1.0.71"
|
||||
|
||||
common = { path = "../../common" }
|
||||
driver-graphics = { path = "../driver-graphics" }
|
||||
graphics-ipc = { path = "../graphics-ipc" }
|
||||
virtio-core = { path = "../../virtio-core" }
|
||||
pcid = { path = "../../pcid" }
|
||||
inputd = { path = "../../inputd" }
|
||||
|
||||
@@ -2,7 +2,8 @@ use std::sync::Arc;
|
||||
|
||||
use common::{dma::Dma, sgl};
|
||||
use driver_graphics::{GraphicsAdapter, GraphicsScheme, Resource};
|
||||
use inputd::{Damage, DisplayHandle};
|
||||
use graphics_ipc::legacy::Damage;
|
||||
use inputd::DisplayHandle;
|
||||
|
||||
use syscall::PAGE_SIZE;
|
||||
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
#![feature(iter_next_chunk)]
|
||||
|
||||
use std::cmp;
|
||||
use std::fs::{File, OpenOptions};
|
||||
use std::io::{Error, Read, Write};
|
||||
use std::mem::size_of;
|
||||
@@ -137,32 +134,6 @@ pub struct VtEvent {
|
||||
pub stride: u32,
|
||||
}
|
||||
|
||||
// Keep synced with orbital's SyncRect
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
#[repr(packed)]
|
||||
pub struct Damage {
|
||||
pub x: i32,
|
||||
pub y: i32,
|
||||
pub width: i32,
|
||||
pub height: i32,
|
||||
}
|
||||
|
||||
impl Damage {
|
||||
#[must_use]
|
||||
pub fn clip(mut self, width: i32, height: i32) -> Self {
|
||||
// Clip damage
|
||||
self.x = cmp::min(self.x, width);
|
||||
if self.x + self.width > width {
|
||||
self.width -= cmp::min(self.width, width - self.x);
|
||||
}
|
||||
self.y = cmp::min(self.y, height);
|
||||
if self.y + self.height > height {
|
||||
self.height = cmp::min(self.height, height - self.y);
|
||||
}
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ProducerHandle(File);
|
||||
|
||||
impl ProducerHandle {
|
||||
|
||||
Reference in New Issue
Block a user