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 timer;
use fb::FramebufferInfo;
use fb::{ColorConfig, FramebufferInfo, FramebufferResult};
pub const IO_REMAP_BASE: usize = bcm2837::consts::IO_BASE;
pub const IO_REMAP_END: usize = bcm2837::consts::KERNEL_OFFSET + 0x4000_1000;
@ -47,7 +47,7 @@ pub fn probe_memory() -> Option<(usize, usize)> {
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 {
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();
}
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"))
}

@ -22,6 +22,6 @@ pub fn init_driver() {
// 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"))
}

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

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

@ -10,7 +10,7 @@ use spin::Mutex;
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::fonts::{Font, Font8x16};
@ -62,17 +62,10 @@ impl<F: Font> ConsoleBuffer<F> {
let off_x = col * F::WIDTH;
let off_y = row * F::HEIGHT;
if let Some(fb) = FRAME_BUFFER.lock().as_mut() {
let (mut foreground, mut background) = match fb.color_depth {
ColorDepth8 => (
ch.attr.foreground.pack8() as u32,
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()),
};
let (mut foreground, mut background) = (
ch.attr.foreground.pack32(fb.color_config),
ch.attr.background.pack32(fb.color_config)
);
if ch.attr.reverse {
core::mem::swap(&mut foreground, &mut background);
}

@ -45,6 +45,18 @@ pub enum 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)]
union ColorBuffer {
base_addr: usize,
@ -105,6 +117,7 @@ impl ColorBuffer {
pub struct Framebuffer {
pub fb_info: FramebufferInfo,
pub color_depth: ColorDepth,
pub color_config: ColorConfig,
buf: ColorBuffer,
}
@ -113,6 +126,7 @@ impl fmt::Debug for Framebuffer {
let mut f = f.debug_struct("Framebuffer");
f.field("fb_info", &self.fb_info);
f.field("color_depth", &self.color_depth);
f.field("color_config", &self.color_config);
f.field("base_addr", unsafe { &self.buf.base_addr });
f.finish()
}
@ -125,7 +139,7 @@ impl Framebuffer {
let probed_info = super::probe_fb_info(width, height, depth);
match probed_info {
Ok((info, addr)) => {
Ok((info, config, addr)) => {
let color_depth = match info.depth {
8 => ColorDepth8,
16 => ColorDepth16,
@ -134,6 +148,7 @@ impl Framebuffer {
};
Ok(Framebuffer {
buf: ColorBuffer::new(color_depth, addr, info.screen_size as usize),
color_config: config,
color_depth,
fb_info: info,
})

Loading…
Cancel
Save