graphics/fbbootlogd: Use the new graphics api
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user