Add ColorConfig support to framebuffer driver

Signed-off-by: Harry Chen <i@harrychen.xyz>
master
Harry Chen 6 years ago
parent 12598a07bf
commit df3eb0e1da

@ -12,7 +12,7 @@ pub mod mailbox;
pub mod serial; pub mod serial;
pub mod timer; pub mod timer;
use fb::FramebufferInfo; use fb::{ColorConfig, FramebufferInfo, FramebufferResult};
pub const IO_REMAP_BASE: usize = bcm2837::consts::IO_BASE; pub const IO_REMAP_BASE: usize = bcm2837::consts::IO_BASE;
pub const IO_REMAP_END: usize = bcm2837::consts::KERNEL_OFFSET + 0x4000_1000; pub const IO_REMAP_END: usize = bcm2837::consts::KERNEL_OFFSET + 0x4000_1000;
@ -47,7 +47,7 @@ pub fn probe_memory() -> Option<(usize, usize)> {
None None
} }
pub fn probe_fb_info(width: u32, height: u32, depth: u32) -> Result<(FramebufferInfo, usize), String> { pub fn probe_fb_info(width: u32, height: u32, depth: u32) -> FramebufferResult {
let (width, height) = if width == 0 || height == 0 { let (width, height) = if width == 0 || height == 0 {
mailbox::framebuffer_get_physical_size()? mailbox::framebuffer_get_physical_size()?
@ -84,5 +84,5 @@ pub fn probe_fb_info(width: u32, height: u32, depth: u32) -> Result<(Framebuffer
))?; ))?;
} }
Ok((info, vaddr)) Ok((info, fb::ColorConfig::BGRA8888, vaddr))
} }

@ -30,6 +30,6 @@ pub fn init_driver() {
// timer::init(); // timer::init();
} }
pub fn probe_fb_info(_width: u32, _height: u32, _depth: u32) -> Result<(fb::FramebufferInfo, usize), String> { pub fn probe_fb_info(_width: u32, _height: u32, _depth: u32) -> fb::FramebufferResult {
Err(String::from("Framebuffer not usable on malta board")) Err(String::from("Framebuffer not usable on malta board"))
} }

@ -22,6 +22,6 @@ pub fn init_driver() {
// timer::init(); // timer::init();
} }
pub fn probe_fb_info(_width: u32, _height: u32, _depth: u32) -> Result<(fb::FramebufferInfo, usize), String> { pub fn probe_fb_info(_width: u32, _height: u32, _depth: u32) -> fb::FramebufferResult {
Err(String::from("Framebuffer not usable on mipssim board")) Err(String::from("Framebuffer not usable on mipssim board"))
} }

@ -10,6 +10,7 @@ pub mod console;
pub mod consts; pub mod consts;
use fb::FramebufferInfo; use fb::FramebufferInfo;
use fb::FramebufferResult;
/// Initialize serial port first /// Initialize serial port first
pub fn init_serial_early() { pub fn init_serial_early() {
@ -24,7 +25,7 @@ pub fn init_driver() {
// timer::init(); // timer::init();
} }
pub fn probe_fb_info(width: u32, height: u32, depth: u32) -> Result<(FramebufferInfo, usize), String> { pub fn probe_fb_info(width: u32, height: u32, depth: u32) -> FramebufferResult {
let fb_info = FramebufferInfo { let fb_info = FramebufferInfo {
xres: 800, xres: 800,
yres: 600, yres: 600,
@ -37,5 +38,5 @@ pub fn probe_fb_info(width: u32, height: u32, depth: u32) -> Result<(Framebuffer
bus_addr: 0xa2000000, bus_addr: 0xa2000000,
screen_size: 800 * 600, screen_size: 800 * 600,
}; };
Ok((fb_info, 0xa2000000)) Ok((fb_info, fb::ColorConfig::RGB332, 0xa2000000))
} }

@ -2,15 +2,10 @@
use crate::util::color::ConsoleColor; use crate::util::color::ConsoleColor;
pub trait FramebufferColor { use super::ColorConfig;
/// pack as 8-bit integer
fn pack8(&self) -> u8;
/// pack as 16-bit integer
fn pack16(&self) -> u16;
/// pack as 32-bit integer pub trait FramebufferColor {
fn pack32(&self) -> u32; fn pack32(&self, config: ColorConfig) -> u32;
} }
#[repr(C)] #[repr(C)]
@ -46,39 +41,24 @@ impl From<ConsoleColor> for RgbColor {
impl FramebufferColor for RgbColor { impl FramebufferColor for RgbColor {
#[inline] #[inline]
fn pack8(&self) -> u8 { fn pack32(&self, config: ColorConfig) -> u32 {
// RGB332 match config {
((self.0 >> 5) << 5) | ((self.1 >> 5) << 2) | (self.2 >> 6) ColorConfig::RGB332 => (((self.0 >> 5) << 5) | ((self.1 >> 5) << 2) | (self.2 >> 6)) as u32,
} ColorConfig::RGB565 => (((self.0 as u16 & 0xF8) << 8) | ((self.1 as u16 & 0xFC) << 3) | (self.2 as u16 >> 3)) as u32,
// FIXME: qemu and low version RPi use RGBA order for 24/32-bit color depth,
#[inline] // but RPi3 B+ uses BGRA order for 24/32-bit color depth.
fn pack16(&self) -> u16 { ColorConfig::BGRA8888 => ((self.0 as u32) << 16) | ((self.1 as u32) << 8) | (self.2 as u32),
// BGR565 _ => unimplemented!()
((self.0 as u16 & 0xF8) << 8) | ((self.1 as u16 & 0xFC) << 3) | (self.2 as u16 >> 3) }
}
#[inline]
fn pack32(&self) -> u32 {
// BGRA8888
// FIXME: qemu and low version RPi use RGBA order for 24/32-bit color depth,
// but RPi3 B+ uses BGRA order for 24/32-bit color depth.
((self.0 as u32) << 16) | ((self.1 as u32) << 8) | (self.2 as u32)
} }
} }
impl FramebufferColor for ConsoleColor { impl FramebufferColor for ConsoleColor {
#[inline] #[inline]
fn pack8(&self) -> u8 { fn pack32(&self, config: ColorConfig) -> u32 {
RgbColor::from(*self).pack8() match config {
} ColorConfig::VgaPalette => *self as u32,
_ => RgbColor::from(*self).pack32(config),
#[inline] }
fn pack16(&self) -> u16 {
RgbColor::from(*self).pack16()
}
#[inline]
fn pack32(&self) -> u32 {
RgbColor::from(*self).pack32()
} }
} }

@ -10,7 +10,7 @@ use spin::Mutex;
use crate::util::escape_parser::{CharacterAttribute, EscapeParser}; use crate::util::escape_parser::{CharacterAttribute, EscapeParser};
use super::fb::{ColorDepth::*, FramebufferInfo, FRAME_BUFFER}; use super::fb::{ColorDepth::*, ColorConfig, FramebufferInfo, FRAME_BUFFER};
use self::color::FramebufferColor; use self::color::FramebufferColor;
use self::fonts::{Font, Font8x16}; use self::fonts::{Font, Font8x16};
@ -62,17 +62,10 @@ impl<F: Font> ConsoleBuffer<F> {
let off_x = col * F::WIDTH; let off_x = col * F::WIDTH;
let off_y = row * F::HEIGHT; let off_y = row * F::HEIGHT;
if let Some(fb) = FRAME_BUFFER.lock().as_mut() { if let Some(fb) = FRAME_BUFFER.lock().as_mut() {
let (mut foreground, mut background) = match fb.color_depth { let (mut foreground, mut background) = (
ColorDepth8 => ( ch.attr.foreground.pack32(fb.color_config),
ch.attr.foreground.pack8() as u32, ch.attr.background.pack32(fb.color_config)
ch.attr.background.pack8() as u32, );
),
ColorDepth16 => (
ch.attr.foreground.pack16() as u32,
ch.attr.background.pack16() as u32,
),
ColorDepth32 => (ch.attr.foreground.pack32(), ch.attr.background.pack32()),
};
if ch.attr.reverse { if ch.attr.reverse {
core::mem::swap(&mut foreground, &mut background); core::mem::swap(&mut foreground, &mut background);
} }

@ -45,6 +45,18 @@ pub enum ColorDepth {
} }
use self::ColorDepth::*; use self::ColorDepth::*;
#[repr(u32)]
#[derive(Debug, Clone, Copy)]
pub enum ColorConfig {
RGB332,
RGB565,
BGRA8888,
VgaPalette,
}
use self::ColorConfig::*;
pub type FramebufferResult = Result<(FramebufferInfo, ColorConfig, usize), String>;
#[repr(C)] #[repr(C)]
union ColorBuffer { union ColorBuffer {
base_addr: usize, base_addr: usize,
@ -105,6 +117,7 @@ impl ColorBuffer {
pub struct Framebuffer { pub struct Framebuffer {
pub fb_info: FramebufferInfo, pub fb_info: FramebufferInfo,
pub color_depth: ColorDepth, pub color_depth: ColorDepth,
pub color_config: ColorConfig,
buf: ColorBuffer, buf: ColorBuffer,
} }
@ -113,6 +126,7 @@ impl fmt::Debug for Framebuffer {
let mut f = f.debug_struct("Framebuffer"); let mut f = f.debug_struct("Framebuffer");
f.field("fb_info", &self.fb_info); f.field("fb_info", &self.fb_info);
f.field("color_depth", &self.color_depth); f.field("color_depth", &self.color_depth);
f.field("color_config", &self.color_config);
f.field("base_addr", unsafe { &self.buf.base_addr }); f.field("base_addr", unsafe { &self.buf.base_addr });
f.finish() f.finish()
} }
@ -125,7 +139,7 @@ impl Framebuffer {
let probed_info = super::probe_fb_info(width, height, depth); let probed_info = super::probe_fb_info(width, height, depth);
match probed_info { match probed_info {
Ok((info, addr)) => { Ok((info, config, addr)) => {
let color_depth = match info.depth { let color_depth = match info.depth {
8 => ColorDepth8, 8 => ColorDepth8,
16 => ColorDepth16, 16 => ColorDepth16,
@ -134,6 +148,7 @@ impl Framebuffer {
}; };
Ok(Framebuffer { Ok(Framebuffer {
buf: ColorBuffer::new(color_depth, addr, info.screen_size as usize), buf: ColorBuffer::new(color_depth, addr, info.screen_size as usize),
color_config: config,
color_depth, color_depth,
fb_info: info, fb_info: info,
}) })

Loading…
Cancel
Save