mirror of
https://github.com/rcore-os/rCore.git
synced 2024-11-22 08:06:17 +04:00
Merge pull request #24 from xy-plus/master
Improve fb driver for userspace gui programs
This commit is contained in:
commit
3bf737eaad
@ -1,6 +1,5 @@
|
||||
//! Framebuffer
|
||||
|
||||
use crate::fs::vga::{fb_fix_screeninfo, fb_var_screeninfo};
|
||||
use alloc::string::String;
|
||||
use core::fmt;
|
||||
use lazy_static::lazy_static;
|
||||
@ -235,20 +234,6 @@ impl Framebuffer {
|
||||
pub fn clear(&mut self) {
|
||||
self.fill(0, self.fb_info.screen_size, 0);
|
||||
}
|
||||
|
||||
pub fn fill_var_screeninfo(&self, var_info: &mut fb_var_screeninfo) {
|
||||
var_info.xres = self.fb_info.xres;
|
||||
var_info.yres = self.fb_info.yres;
|
||||
var_info.xres_virtual = self.fb_info.xres_virtual;
|
||||
var_info.yres_virtual = self.fb_info.yres_virtual;
|
||||
var_info.xoffset = self.fb_info.xoffset;
|
||||
var_info.yoffset = self.fb_info.yoffset;
|
||||
var_info.bits_per_pixel = self.fb_info.depth as u32;
|
||||
}
|
||||
|
||||
pub fn fill_fix_screeninfo(&self, fix_info: &mut fb_fix_screeninfo) {
|
||||
fix_info.line_length = self.fb_info.xres * self.fb_info.depth as u32 / 8
|
||||
}
|
||||
}
|
||||
|
||||
use rcore_console::embedded_graphics::prelude::*;
|
||||
|
@ -399,6 +399,21 @@ pub fn virtio_gpu_init(node: &Node) {
|
||||
|
||||
setup_framebuffer(&mut driver);
|
||||
|
||||
use super::fb;
|
||||
fb::init(fb::FramebufferInfo {
|
||||
xres: driver.rect.width,
|
||||
yres: driver.rect.height,
|
||||
xres_virtual: driver.rect.width,
|
||||
yres_virtual: driver.rect.height,
|
||||
xoffset: 0,
|
||||
yoffset: 0,
|
||||
depth: fb::ColorDepth::ColorDepth32,
|
||||
format: fb::ColorFormat::RGBA8888,
|
||||
paddr: virt_to_phys(driver.frame_buffer),
|
||||
vaddr: driver.frame_buffer,
|
||||
screen_size: (driver.rect.width * driver.rect.height * 4) as usize,
|
||||
});
|
||||
|
||||
let driver = Arc::new(VirtIOGpuDriver(Mutex::new(driver)));
|
||||
IRQ_MANAGER.write().register_all(driver.clone());
|
||||
DRIVERS.write().push(driver);
|
||||
|
@ -1,6 +1,6 @@
|
||||
use rcore_fs::vfs::*;
|
||||
|
||||
use crate::drivers::gpu::fb::FRAME_BUFFER;
|
||||
use crate::drivers::gpu::fb::{ColorFormat, FramebufferInfo, FRAME_BUFFER};
|
||||
use crate::memory::phys_to_virt;
|
||||
use alloc::{string::String, sync::Arc, vec::Vec};
|
||||
use core::any::Any;
|
||||
@ -56,19 +56,21 @@ impl INode for Vga {
|
||||
})
|
||||
}
|
||||
fn io_control(&self, cmd: u32, data: usize) -> Result<()> {
|
||||
info!("cmd {:#x} , data {:#x} vga not support ioctl !", cmd, data);
|
||||
const FBIOGET_VSCREENINFO: u32 = 0x4600;
|
||||
const FBIOGET_FSCREENINFO: u32 = 0x4602;
|
||||
|
||||
match cmd {
|
||||
FBIOGET_FSCREENINFO => {
|
||||
let fb_fix_info = unsafe { &mut *(data as *mut fb_fix_screeninfo) };
|
||||
let fb_fix_info = unsafe { &mut *(data as *mut FbFixScreeninfo) };
|
||||
if let Some(fb) = FRAME_BUFFER.lock().as_ref() {
|
||||
fb.fill_fix_screeninfo(fb_fix_info);
|
||||
fb_fix_info.fill_from(&fb.fb_info);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
FBIOGET_VSCREENINFO => {
|
||||
let fb_var_info = unsafe { &mut *(data as *mut fb_var_screeninfo) };
|
||||
let fb_var_info = unsafe { &mut *(data as *mut FbVarScreeninfo) };
|
||||
if let Some(fb) = FRAME_BUFFER.lock().as_ref() {
|
||||
fb.fill_var_screeninfo(fb_var_info);
|
||||
fb_var_info.fill_from(&fb.fb_info);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@ -77,84 +79,218 @@ impl INode for Vga {
|
||||
Err(FsError::NotSupported)
|
||||
}
|
||||
}
|
||||
//let fb_fix_info = unsafe{ &mut *(data as *mut fb_fix_screeninfo) };
|
||||
//Ok(())
|
||||
}
|
||||
fn as_any_ref(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
const FBIOGET_FSCREENINFO: u32 = 0x4602;
|
||||
const FBIOGET_VSCREENINFO: u32 = 0x4600;
|
||||
#[repr(u32)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
enum FbType {
|
||||
/// Packed Pixels
|
||||
PackedPixels = 0,
|
||||
/// Non interleaved planes
|
||||
Planes = 1,
|
||||
/// Interleaved planes
|
||||
InterleavedPlanes = 2,
|
||||
/// Text/attributes
|
||||
Text = 3,
|
||||
/// EGA/VGA planes
|
||||
VgaPlanes = 4,
|
||||
/// Type identified by a V4L2 FOURCC
|
||||
FourCC = 5,
|
||||
}
|
||||
|
||||
#[repr(u32)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
enum FbVisual {
|
||||
/// Monochr. 1=Black 0=White
|
||||
Mono01 = 0,
|
||||
/// Monochr. 1=White 0=Black
|
||||
Mono10 = 1,
|
||||
/// True color
|
||||
TrueColor = 2,
|
||||
/// Pseudo color (like atari)
|
||||
PseudoColor = 3,
|
||||
/// Direct color
|
||||
DirectColor = 4,
|
||||
/// Pseudo color readonly
|
||||
StaticPseudoColor = 5,
|
||||
/// Visual identified by a V4L2 FOURCC
|
||||
FourCC = 6,
|
||||
}
|
||||
|
||||
/// No hardware accelerator
|
||||
const FB_ACCEL_NONE: u32 = 0;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct fb_fix_screeninfo {
|
||||
pub id: [u8; 16], /* identification string eg "TT Builtin" */
|
||||
pub smem_start: u64, /* Start of frame buffer mem */
|
||||
/* (physical address) */
|
||||
pub smem_len: u32, /* Length of frame buffer mem */
|
||||
pub _type: u32, /* see FB_TYPE_* */
|
||||
pub type_aux: u32, /* Interleave for interleaved Planes */
|
||||
pub visual: u32, /* see FB_VISUAL_* */
|
||||
pub xpanstep: u16, /* zero if no hardware panning */
|
||||
pub ypanstep: u16, /* zero if no hardware panning */
|
||||
pub ywrapstep: u16, /* zero if no hardware ywrap */
|
||||
pub line_length: u32, /* length of a line in bytes */
|
||||
pub mmio_start: u64, /* Start of Memory Mapped I/O */
|
||||
/* (physical address) */
|
||||
pub mmio_len: u32, /* Length of Memory Mapped I/O */
|
||||
pub accel: u32, /* Indicate to driver which */
|
||||
/* specific chip/card we have */
|
||||
pub capabilities: u16, /* see FB_CAP_* */
|
||||
pub reserved: [u16; 2], /* Reserved for future compatibility */
|
||||
#[derive(Debug)]
|
||||
struct FbFixScreeninfo {
|
||||
/// identification string eg "TT Builtin"
|
||||
id: [u8; 16],
|
||||
/// Start of frame buffer mem (physical address)
|
||||
smem_start: u64,
|
||||
/// Length of frame buffer mem
|
||||
smem_len: u32,
|
||||
/// see FB_TYPE_*
|
||||
type_: FbType,
|
||||
/// Interleave for interleaved Planes
|
||||
type_aux: u32,
|
||||
/// see FB_VISUAL_*
|
||||
visual: FbVisual,
|
||||
/// zero if no hardware panning
|
||||
xpanstep: u16,
|
||||
/// zero if no hardware panning
|
||||
ypanstep: u16,
|
||||
/// zero if no hardware ywrap
|
||||
ywrapstep: u16,
|
||||
/// length of a line in bytes
|
||||
line_length: u32,
|
||||
/// Start of Memory Mapped I/O (physical address)
|
||||
mmio_start: u64,
|
||||
/// Length of Memory Mapped I/O
|
||||
mmio_len: u32,
|
||||
/// Indicate to driver which specific chip/card we have
|
||||
accel: u32,
|
||||
/// see FB_CAP_*
|
||||
capabilities: u16,
|
||||
/// Reserved for future compatibility
|
||||
reserved: [u16; 2],
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct fb_var_screeninfo {
|
||||
pub xres: u32, /* visible resolution */
|
||||
pub yres: u32,
|
||||
pub xres_virtual: u32, /* virtual resolution */
|
||||
pub yres_virtual: u32,
|
||||
pub xoffset: u32, /* offset from virtual to visible */
|
||||
pub yoffset: u32, /* resolution */
|
||||
#[derive(Debug)]
|
||||
struct FbVarScreeninfo {
|
||||
/// visible resolution x
|
||||
xres: u32,
|
||||
/// visible resolution y
|
||||
yres: u32,
|
||||
/// virtual resolution x
|
||||
xres_virtual: u32,
|
||||
/// virtual resolution y
|
||||
yres_virtual: u32,
|
||||
/// offset from virtual to visible x
|
||||
xoffset: u32,
|
||||
/// offset from virtual to visible y
|
||||
yoffset: u32,
|
||||
|
||||
pub bits_per_pixel: u32, /* guess what */
|
||||
pub grayscale: u32, /* 0 = color, 1 = grayscale, */
|
||||
/* >1 = FOURCC */
|
||||
pub red: fb_bitfield, /* bitfield in fb mem if true color, */
|
||||
pub green: fb_bitfield, /* else only length is significant */
|
||||
pub blue: fb_bitfield,
|
||||
pub transp: fb_bitfield, /* transparency */
|
||||
/// guess what
|
||||
bits_per_pixel: u32,
|
||||
/// 0 = color, 1 = grayscale, >1 = FOURCC
|
||||
grayscale: u32,
|
||||
/// bitfield in fb mem if true color, else only length is significant
|
||||
red: FbBitfield,
|
||||
green: FbBitfield,
|
||||
blue: FbBitfield,
|
||||
transp: FbBitfield,
|
||||
|
||||
pub nonstd: u32, /* != 0 Non standard pixel format */
|
||||
/// != 0 Non standard pixel format
|
||||
nonstd: u32,
|
||||
|
||||
pub activate: u32, /* see FB_ACTIVATE_* */
|
||||
/// see FB_ACTIVATE_*
|
||||
activate: u32,
|
||||
|
||||
pub height: u32, /* height of picture in mm */
|
||||
pub width: u32, /* width of picture in mm */
|
||||
|
||||
pub accel_flags: u32, /* (OBSOLETE) see fb_info.flags */
|
||||
/// height of picture in mm
|
||||
height: u32,
|
||||
/// width of picture in mm
|
||||
width: u32,
|
||||
/// (OBSOLETE) see fb_info.flags
|
||||
accel_flags: u32,
|
||||
|
||||
/* Timing: All values in pixclocks, except pixclock (of course) */
|
||||
pub pixclock: u32, /* pixel clock in ps (pico seconds) */
|
||||
pub left_margin: u32, /* time from sync to picture */
|
||||
pub right_margin: u32, /* time from picture to sync */
|
||||
pub upper_margin: u32, /* time from sync to picture */
|
||||
pub lower_margin: u32,
|
||||
pub hsync_len: u32, /* length of horizontal sync */
|
||||
pub vsync_len: u32, /* length of vertical sync */
|
||||
pub sync: u32, /* see FB_SYNC_* */
|
||||
pub vmode: u32, /* see FB_VMODE_* */
|
||||
pub rotate: u32, /* angle we rotate counter clockwise */
|
||||
pub colorspace: u32, /* colorspace for FOURCC-based modes */
|
||||
pub reserved: [u32; 4], /* Reserved for future compatibility */
|
||||
/// pixel clock in ps (pico seconds)
|
||||
pixclock: u32,
|
||||
/// time from sync to picture
|
||||
left_margin: u32,
|
||||
/// time from picture to sync
|
||||
right_margin: u32,
|
||||
/// time from sync to picture
|
||||
upper_margin: u32,
|
||||
lower_margin: u32,
|
||||
/// length of horizontal sync
|
||||
hsync_len: u32,
|
||||
/// length of vertical sync
|
||||
vsync_len: u32,
|
||||
/// see FB_SYNC_*
|
||||
sync: u32,
|
||||
/// see FB_VMODE_*
|
||||
vmode: u32,
|
||||
/// angle we rotate counter clockwise
|
||||
rotate: u32,
|
||||
/// colorspace for FOURCC-based modes
|
||||
colorspace: u32,
|
||||
/// Reserved for future compatibility
|
||||
reserved: [u32; 4],
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct fb_bitfield {
|
||||
pub offset: u32, /* beginning of bitfield */
|
||||
pub length: u32, /* length of bitfield */
|
||||
pub msb_right: u32, /* != 0 : Most significant bit is */
|
||||
/* right */
|
||||
#[derive(Debug)]
|
||||
struct FbBitfield {
|
||||
/// beginning of bitfield
|
||||
offset: u32,
|
||||
/// length of bitfield
|
||||
length: u32,
|
||||
/// != 0 : Most significant bit is right
|
||||
msb_right: u32,
|
||||
}
|
||||
|
||||
impl FbVarScreeninfo {
|
||||
fn fill_from(&mut self, fb_info: &FramebufferInfo) {
|
||||
self.xres = fb_info.xres;
|
||||
self.yres = fb_info.yres;
|
||||
self.xres_virtual = fb_info.xres_virtual;
|
||||
self.yres_virtual = fb_info.yres_virtual;
|
||||
self.xoffset = fb_info.xoffset;
|
||||
self.yoffset = fb_info.yoffset;
|
||||
self.bits_per_pixel = fb_info.depth as u32;
|
||||
let (rl, gl, bl, al, ro, go, bo, ao) = match fb_info.format {
|
||||
ColorFormat::RGB332 => (3, 3, 2, 0, 5, 3, 0, 0),
|
||||
ColorFormat::RGB565 => (5, 6, 5, 0, 11, 5, 0, 0),
|
||||
ColorFormat::RGBA8888 => (8, 8, 8, 8, 16, 8, 0, 24),
|
||||
ColorFormat::BGRA8888 => (8, 8, 8, 8, 0, 8, 16, 24),
|
||||
ColorFormat::VgaPalette => unimplemented!(),
|
||||
};
|
||||
self.blue = FbBitfield {
|
||||
offset: bo,
|
||||
length: bl,
|
||||
msb_right: 1,
|
||||
};
|
||||
self.green = FbBitfield {
|
||||
offset: go,
|
||||
length: gl,
|
||||
msb_right: 1,
|
||||
};
|
||||
self.red = FbBitfield {
|
||||
offset: ro,
|
||||
length: rl,
|
||||
msb_right: 1,
|
||||
};
|
||||
self.transp = FbBitfield {
|
||||
offset: ao,
|
||||
length: al,
|
||||
msb_right: 1,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
impl FbFixScreeninfo {
|
||||
fn fill_from(&mut self, fb_info: &FramebufferInfo) {
|
||||
self.smem_start = fb_info.paddr as u64;
|
||||
self.smem_len = fb_info.screen_size as u32;
|
||||
|
||||
self.type_ = FbType::PackedPixels;
|
||||
// self.type_aux = fb_info.type_aux;
|
||||
self.visual = FbVisual::TrueColor;
|
||||
|
||||
// self.xpanstep = 0;
|
||||
// self.ypanstep = 0;
|
||||
// self.ywrapstep = 0;
|
||||
|
||||
self.line_length = fb_info.xres * fb_info.depth as u32 / 8;
|
||||
|
||||
self.mmio_start = 0;
|
||||
self.mmio_len = 0;
|
||||
self.accel = FB_ACCEL_NONE;
|
||||
}
|
||||
}
|
||||
|
@ -147,6 +147,18 @@ impl Syscall<'_> {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn sys_pselect6(
|
||||
&mut self,
|
||||
nfds: usize,
|
||||
read: *mut u32,
|
||||
write: *mut u32,
|
||||
err: *mut u32,
|
||||
timeout: *const TimeVal,
|
||||
_sigset: *const u32,
|
||||
) -> SysResult {
|
||||
self.sys_select(nfds, read, write, err, timeout)
|
||||
}
|
||||
|
||||
pub fn sys_select(
|
||||
&mut self,
|
||||
nfds: usize,
|
||||
@ -159,7 +171,9 @@ impl Syscall<'_> {
|
||||
"select: nfds: {}, read: {:?}, write: {:?}, err: {:?}, timeout: {:?}",
|
||||
nfds, read, write, err, timeout
|
||||
);
|
||||
|
||||
if nfds as u64 == 0 {
|
||||
return Ok(0);
|
||||
}
|
||||
let proc = self.process();
|
||||
let mut read_fds = FdSet::new(&self.vm(), read, nfds)?;
|
||||
let mut write_fds = FdSet::new(&self.vm(), write, nfds)?;
|
||||
|
@ -154,6 +154,14 @@ impl Syscall<'_> {
|
||||
),
|
||||
|
||||
// io multiplexing
|
||||
SYS_PSELECT6 => self.sys_pselect6(
|
||||
args[0],
|
||||
args[1] as *mut u32,
|
||||
args[2] as *mut u32,
|
||||
args[3] as *mut u32,
|
||||
args[4] as *const TimeVal,
|
||||
args[5] as *const u32,
|
||||
),
|
||||
SYS_PPOLL => {
|
||||
self.sys_ppoll(args[0] as *mut PollFd, args[1], args[2] as *const TimeSpec)
|
||||
} // ignore sigmask
|
||||
|
Loading…
Reference in New Issue
Block a user