Support bootloader stride
This commit is contained in:
@@ -7,13 +7,14 @@ use super::FONT;
|
||||
pub struct Display {
|
||||
pub width: usize,
|
||||
pub height: usize,
|
||||
pub stride: usize,
|
||||
pub onscreen: &'static mut [u32],
|
||||
pub offscreen: Option<Box<[u32]>>
|
||||
}
|
||||
|
||||
impl Display {
|
||||
pub fn new(width: usize, height: usize, onscreen_ptr: *mut u32) -> Display {
|
||||
let size = width * height;
|
||||
pub fn new(width: usize, height: usize, stride: usize, onscreen_ptr: *mut u32) -> Display {
|
||||
let size = stride * height;
|
||||
let onscreen = unsafe {
|
||||
ptr::write_bytes(onscreen_ptr, 0, size);
|
||||
slice::from_raw_parts_mut(onscreen_ptr, size)
|
||||
@@ -21,6 +22,7 @@ impl Display {
|
||||
Display {
|
||||
width,
|
||||
height,
|
||||
stride,
|
||||
onscreen,
|
||||
offscreen: None,
|
||||
}
|
||||
@@ -36,7 +38,7 @@ impl Display {
|
||||
/// Draw a character
|
||||
pub fn char(&mut self, x: usize, y: usize, character: char, color: u32) {
|
||||
if x + 8 <= self.width && y + 16 <= self.height {
|
||||
let mut dst = self.data_mut().as_mut_ptr() as usize + (y * self.width + x) * 4;
|
||||
let mut dst = self.data_mut().as_mut_ptr() as usize + (y * self.stride + x) * 4;
|
||||
|
||||
let font_i = 16 * (character as usize);
|
||||
if font_i + 16 <= FONT.len() {
|
||||
@@ -47,7 +49,7 @@ impl Display {
|
||||
unsafe { *((dst + col * 4) as *mut u32) = color; }
|
||||
}
|
||||
}
|
||||
dst += self.width * 4;
|
||||
dst += self.stride * 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -55,8 +57,8 @@ impl Display {
|
||||
|
||||
/// Scroll the screen
|
||||
pub fn scroll(&mut self, lines: usize) {
|
||||
let offset = cmp::min(self.height, lines) * self.width;
|
||||
let size = (self.width * self.height) - offset;
|
||||
let offset = cmp::min(self.height, lines) * self.stride;
|
||||
let size = (self.stride * self.height) - offset;
|
||||
unsafe {
|
||||
let ptr = self.data_mut().as_mut_ptr();
|
||||
ptr::copy(ptr.add(offset), ptr, size);
|
||||
@@ -67,12 +69,12 @@ impl Display {
|
||||
/// Sync from offscreen to onscreen, unsafe because it trusts provided x, y, w, h
|
||||
pub unsafe fn sync(&mut self, x: usize, y: usize, w: usize, mut h: usize) {
|
||||
if let Some(offscreen) = &self.offscreen {
|
||||
let mut offset = y * self.width + x;
|
||||
let mut offset = y * self.stride + x;
|
||||
while h > 0 {
|
||||
self.onscreen[offset..offset+w].copy_from_slice(
|
||||
&offscreen[offset..offset+w]
|
||||
);
|
||||
offset += self.width;
|
||||
offset += self.stride;
|
||||
h -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ pub fn init(env: &[u8]) {
|
||||
let mut virt = 0;
|
||||
let mut width = 0;
|
||||
let mut height = 0;
|
||||
let mut stride = 0;
|
||||
|
||||
//TODO: should errors be reported?
|
||||
for line in str::from_utf8(env).unwrap_or("").lines() {
|
||||
@@ -42,19 +43,23 @@ pub fn init(env: &[u8]) {
|
||||
if name == "FRAMEBUFFER_HEIGHT" {
|
||||
height = usize::from_str_radix(value, 16).unwrap_or(0);
|
||||
}
|
||||
|
||||
if name == "FRAMEBUFFER_STRIDE" {
|
||||
stride = usize::from_str_radix(value, 16).unwrap_or(0);
|
||||
}
|
||||
}
|
||||
|
||||
*FRAMEBUFFER.lock() = (phys, virt, width * height * 4);
|
||||
*FRAMEBUFFER.lock() = (phys, virt, stride * height * 4);
|
||||
|
||||
if phys == 0 || virt == 0 || width == 0 || height == 0 {
|
||||
if phys == 0 || virt == 0 || width == 0 || height == 0 || stride == 0 {
|
||||
println!("Framebuffer not found");
|
||||
return;
|
||||
}
|
||||
|
||||
println!("Framebuffer {}x{} at {:X} mapped to {:X}", width, height, phys, virt);
|
||||
println!("Framebuffer {}x{} stride {} at {:X} mapped to {:X}", width, height, stride, phys, virt);
|
||||
|
||||
{
|
||||
let display = Display::new(width, height, virt as *mut u32);
|
||||
let display = Display::new(width, height, stride, virt as *mut u32);
|
||||
let debug_display = DebugDisplay::new(display);
|
||||
*DEBUG_DISPLAY.lock() = Some(debug_display);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user