Move the framebuffer resizing code into a FrameBuffer method

This commit is contained in:
bjorn3
2024-07-19 22:12:48 +02:00
parent 857773393d
commit 53c02b5322
3 changed files with 59 additions and 54 deletions
+52 -17
View File
@@ -1,6 +1,9 @@
use std::{ptr, slice};
use std::ptr;
use syscall::PAGE_SIZE;
pub struct FrameBuffer {
pub onscreen: *mut [u32],
pub phys: usize,
pub width: usize,
pub height: usize,
@@ -8,8 +11,25 @@ pub struct FrameBuffer {
}
impl FrameBuffer {
pub fn new(phys: usize, width: usize, height: usize, stride: usize) -> Self {
pub unsafe fn new(phys: usize, width: usize, height: usize, stride: usize) -> Self {
let size = stride * height;
let virt = common::physmap(
phys,
size * 4,
common::Prot {
read: true,
write: true,
},
common::MemoryType::WriteCombining,
)
.expect("vesad: failed to map framebuffer") as *mut u32;
//TODO: should we clear the framebuffer here?
ptr::write_bytes(virt, 0, size);
let onscreen = ptr::slice_from_raw_parts_mut(virt, size);
Self {
onscreen,
phys,
width,
height,
@@ -17,7 +37,7 @@ impl FrameBuffer {
}
}
pub fn parse(var: &str) -> Option<Self> {
pub unsafe fn parse(var: &str) -> Option<Self> {
fn parse_number(part: &str) -> Option<usize> {
let (start, radix) = if part.starts_with("0x") {
(2, 16)
@@ -41,20 +61,35 @@ impl FrameBuffer {
Some(Self::new(phys, width, height, stride))
}
pub unsafe fn map(&mut self) -> syscall::Result<&'static mut [u32]> {
let size = self.stride * self.height;
let virt = common::physmap(
self.phys,
size * 4,
common::Prot {
read: true,
write: true,
},
common::MemoryType::WriteCombining,
)? as *mut u32;
//TODO: should we clear the framebuffer here?
ptr::write_bytes(virt, 0, size);
pub unsafe fn resize(&mut self, width: usize, height: usize, stride: usize) {
// Unmap old onscreen
unsafe {
let slice = self.onscreen;
libredox::call::munmap(slice.cast(), (slice.len() * 4).next_multiple_of(PAGE_SIZE))
.expect("vesad: failed to unmap framebuffer");
}
Ok(slice::from_raw_parts_mut(virt, size))
// Map new onscreen
self.onscreen = unsafe {
let size = stride * height;
let onscreen_ptr = common::physmap(
self.phys,
size * 4,
common::Prot {
read: true,
write: true,
},
common::MemoryType::WriteCombining,
)
.expect("vesad: failed to map framebuffer") as *mut u32;
ptr::write_bytes(onscreen_ptr, 0, size);
ptr::slice_from_raw_parts_mut(onscreen_ptr, size)
};
// Update size
self.width = width;
self.height = height;
self.stride = stride;
}
}
+2 -2
View File
@@ -54,12 +54,12 @@ fn main() {
return;
}
let mut framebuffers = vec![FrameBuffer::new(phys, width, height, stride)];
let mut framebuffers = vec![unsafe { FrameBuffer::new(phys, width, height, stride) }];
//TODO: ideal maximum number of outputs?
for i in 1..1024 {
match env::var(&format!("FRAMEBUFFER{}", i)) {
Ok(var) => match FrameBuffer::parse(&var) {
Ok(var) => match unsafe { FrameBuffer::parse(&var) } {
Some(fb) => {
println!(
"vesad: framebuffer {}: {}x{} stride {} at 0x{:X}",
+5 -35
View File
@@ -1,9 +1,7 @@
use std::collections::BTreeMap;
use std::{mem, ptr, slice, str};
use std::str;
use syscall::{
Error, EventFlags, MapFlags, Result, SchemeMut, EBADF, EINVAL, ENOENT, O_NONBLOCK, PAGE_SIZE,
};
use syscall::{Error, EventFlags, MapFlags, Result, SchemeMut, EBADF, EINVAL, ENOENT, O_NONBLOCK};
use crate::{framebuffer::FrameBuffer, screen::GraphicScreen};
@@ -43,7 +41,7 @@ impl DisplayScheme {
let mut onscreens = Vec::new();
for fb in framebuffers.iter_mut() {
onscreens.push(unsafe { fb.map().expect("vesad: failed to map framebuffer") });
onscreens.push(unsafe { &mut *fb.onscreen });
}
let mut vts = BTreeMap::<VtIndex, BTreeMap<ScreenIndex, GraphicScreen>>::new();
@@ -96,39 +94,11 @@ impl DisplayScheme {
fb_i, width, height, stride
);
// Unmap old onscreen
unsafe {
let slice = mem::take(&mut self.onscreens[fb_i]);
libredox::call::munmap(
slice.as_mut_ptr().cast(),
(slice.len() * 4).next_multiple_of(PAGE_SIZE),
)
.expect("vesad: failed to unmap framebuffer");
self.framebuffers[fb_i].resize(width, height, stride);
self.onscreens[fb_i] = &mut *self.framebuffers[fb_i].onscreen;
}
// Map new onscreen
self.onscreens[fb_i] = unsafe {
let size = stride * height;
let onscreen_ptr = common::physmap(
self.framebuffers[fb_i].phys,
size * 4,
common::Prot {
read: true,
write: true,
},
common::MemoryType::WriteCombining,
)
.expect("vesad: failed to map framebuffer") as *mut u32;
ptr::write_bytes(onscreen_ptr, 0, size);
slice::from_raw_parts_mut(onscreen_ptr, size)
};
// Update size
self.framebuffers[fb_i].width = width;
self.framebuffers[fb_i].height = height;
self.framebuffers[fb_i].stride = stride;
// Resize screens
for (vt_i, screens) in self.vts.iter_mut() {
for (screen_i, screen) in screens.iter_mut() {