graphics/fbbootlogd: Use the new graphics api

This commit is contained in:
bjorn3
2025-07-02 15:37:35 +02:00
parent 4f7b0eb6b6
commit cc0db37209
2 changed files with 97 additions and 6 deletions
+33
View File
@@ -226,4 +226,37 @@ impl TextScreen {
damage
}
pub fn resize(&mut self, old_map: &mut DisplayMap, new_map: &mut DisplayMap) {
// FIXME fold row when target is narrower and maybe unfold when it is wider
fn copy_row(
old_map: &mut DisplayMap,
new_map: &mut DisplayMap,
from_row: usize,
to_row: usize,
) {
for x in 0..cmp::min(old_map.width, new_map.width) {
let old_idx = from_row * old_map.width + x;
let new_idx = to_row * new_map.width + x;
unsafe {
(*new_map.offscreen)[new_idx] = (*old_map.offscreen)[old_idx];
}
}
}
if new_map.height >= old_map.height {
for row in 0..old_map.height {
copy_row(old_map, new_map, row, row);
}
} else {
let deleted_rows = (old_map.height - new_map.height).div_ceil(16);
for row in 0..new_map.height {
if row + (deleted_rows + 1) * 16 >= old_map.height {
break;
}
copy_row(old_map, new_map, row + deleted_rows * 16, row);
}
self.console.state.y = self.console.state.y.saturating_sub(deleted_rows);
}
}
}
+64 -6
View File
@@ -1,12 +1,15 @@
use std::collections::VecDeque;
use std::ptr;
use graphics_ipc::v1::V1GraphicsHandle;
use console_draw::TextScreen;
use graphics_ipc::v2::V2GraphicsHandle;
use inputd::ConsumerHandle;
use redox_scheme::Scheme;
use syscall::{Error, Result, EINVAL, ENOENT};
pub struct DisplayMap {
display_handle: V1GraphicsHandle,
display_handle: V2GraphicsHandle,
fb: usize,
inner: graphics_ipc::v1::DisplayMap,
}
@@ -30,18 +33,24 @@ impl FbbootlogScheme {
}
pub fn handle_handoff(&mut self) {
let new_display_handle = match self.input_handle.open_display() {
Ok(display) => V1GraphicsHandle::from_file(display).unwrap(),
let new_display_handle = match self.input_handle.open_display_v2() {
Ok(display) => V2GraphicsHandle::from_file(display).unwrap(),
Err(err) => {
eprintln!("fbbootlogd: No display present yet: {err}");
return;
}
};
match new_display_handle.map_display() {
let (width, height) = new_display_handle.display_size(0).unwrap();
let fb = new_display_handle
.create_dumb_framebuffer(width, height)
.unwrap();
match new_display_handle.map_dumb_framebuffer(fb, width, height) {
Ok(display_map) => {
self.display_map = Some(DisplayMap {
display_handle: new_display_handle,
fb,
inner: display_map,
});
@@ -52,6 +61,53 @@ impl FbbootlogScheme {
}
}
}
fn handle_resize(map: &mut DisplayMap, text_screen: &mut TextScreen) {
let (width, height) = match map.display_handle.display_size(0) {
Ok((width, height)) => (width, height),
Err(err) => {
eprintln!("fbbootlogd: failed to get display size: {}", err);
(map.inner.width() as u32, map.inner.height() as u32)
}
};
if width as usize != map.inner.width() || height as usize != map.inner.height() {
match map.display_handle.create_dumb_framebuffer(width, height) {
Ok(fb) => match map.display_handle.map_dumb_framebuffer(fb, width, height) {
Ok(mut new_map) => {
let count = new_map.ptr().len();
unsafe {
ptr::write_bytes(new_map.ptr_mut() as *mut u32, 0, count);
}
text_screen.resize(
&mut console_draw::DisplayMap {
offscreen: map.inner.ptr_mut(),
width: map.inner.width(),
height: map.inner.height(),
},
&mut console_draw::DisplayMap {
offscreen: new_map.ptr_mut(),
width: new_map.width(),
height: new_map.height(),
},
);
map.fb = fb;
map.inner = new_map;
eprintln!("fbbootlogd: mapped display");
}
Err(err) => {
eprintln!("fbbootlogd: failed to open display: {}", err);
}
},
Err(err) => {
eprintln!("fbbootlogd: failed to create framebuffer: {}", err);
}
}
}
}
}
impl Scheme for FbbootlogScheme {
@@ -91,6 +147,8 @@ impl Scheme for FbbootlogScheme {
fn write(&mut self, _id: usize, buf: &[u8], _offset: u64, _fcntl_flags: u32) -> Result<usize> {
if let Some(map) = &mut self.display_map {
Self::handle_resize(map, &mut self.text_screen);
let damage = self.text_screen.write(
&mut console_draw::DisplayMap {
offscreen: map.inner.ptr_mut(),
@@ -102,7 +160,7 @@ impl Scheme for FbbootlogScheme {
);
if let Some(map) = &self.display_map {
map.display_handle.sync_rect(damage).unwrap();
map.display_handle.update_plane(0, map.fb, damage).unwrap();
}
}