mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-19 09:06:32 +00:00
支持绘制24位深和16位深显示缓冲区 (#640)
* 修复了初始化时显示,边界条件的一个bug * 解决了内存未初始前字体显示的兼容性问题 * 支持绘制24位深和16位深显示缓冲区
This commit is contained in:
@ -45,6 +45,7 @@ impl<'a> BitmapFont<'a> {
|
||||
|
||||
#[inline(always)]
|
||||
pub fn char_map(&self, character: char) -> &'a [u8] {
|
||||
//获得ASCII的index
|
||||
let index = self.glyph_mapping.index(character);
|
||||
let pos = index * self.bytes_per_char;
|
||||
|
||||
|
@ -47,7 +47,7 @@ pub enum ScmFramworkType {
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum ScmBuffer {
|
||||
DeviceBuffer(VirtAddr),
|
||||
DoubleBuffer(Arc<SpinLock<Box<[u32]>>>),
|
||||
DoubleBuffer(Arc<SpinLock<Box<[u8]>>>),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@ -81,15 +81,15 @@ impl ScmBufferInfo {
|
||||
} else {
|
||||
let device_buffer_guard = video_refresh_manager().device_buffer();
|
||||
|
||||
let buf_space: Arc<SpinLock<Box<[u32]>>> = Arc::new(SpinLock::new(
|
||||
vec![0u32; (device_buffer_guard.size / 4) as usize].into_boxed_slice(),
|
||||
let buf_space: Arc<SpinLock<Box<[u8]>>> = Arc::new(SpinLock::new(
|
||||
vec![0u8; (device_buffer_guard.size / 4) as usize].into_boxed_slice(),
|
||||
));
|
||||
|
||||
assert!(buf_type.contains(ScmBufferFlag::SCM_BF_DB));
|
||||
|
||||
assert_eq!(
|
||||
device_buffer_guard.size as usize,
|
||||
buf_space.lock().len() * core::mem::size_of::<u32>()
|
||||
buf_space.lock().len() * core::mem::size_of::<u8>()
|
||||
);
|
||||
|
||||
// 创建双缓冲区
|
||||
@ -155,11 +155,11 @@ impl ScmBufferInfo {
|
||||
ScmBuffer::DeviceBuffer(vaddr) => {
|
||||
let len = self.buf_size() / core::mem::size_of::<u32>();
|
||||
let self_buf_guard =
|
||||
unsafe { core::slice::from_raw_parts_mut(vaddr.data() as *mut u32, len) };
|
||||
unsafe { core::slice::from_raw_parts_mut(vaddr.data() as *mut u8, len) };
|
||||
match &src.buf {
|
||||
ScmBuffer::DeviceBuffer(vaddr) => {
|
||||
let src_buf_guard =
|
||||
unsafe { core::slice::from_raw_parts(vaddr.data() as *const u32, len) };
|
||||
unsafe { core::slice::from_raw_parts(vaddr.data() as *const u8, len) };
|
||||
self_buf_guard.copy_from_slice(src_buf_guard);
|
||||
}
|
||||
ScmBuffer::DoubleBuffer(double_buffer) => {
|
||||
@ -173,9 +173,9 @@ impl ScmBufferInfo {
|
||||
let mut double_buffer_guard = double_buffer.lock();
|
||||
match &src.buf {
|
||||
ScmBuffer::DeviceBuffer(vaddr) => {
|
||||
let len = src.buf_size() / core::mem::size_of::<u32>();
|
||||
let len = src.buf_size() / core::mem::size_of::<u8>();
|
||||
double_buffer_guard.as_mut().copy_from_slice(unsafe {
|
||||
core::slice::from_raw_parts(vaddr.data() as *const u32, len)
|
||||
core::slice::from_raw_parts(vaddr.data() as *const u8, len)
|
||||
});
|
||||
}
|
||||
ScmBuffer::DoubleBuffer(double_buffer) => {
|
||||
|
@ -17,6 +17,7 @@ use core::{
|
||||
fmt::Debug,
|
||||
intrinsics::unlikely,
|
||||
ops::{Add, AddAssign, Sub},
|
||||
ptr::copy_nonoverlapping,
|
||||
sync::atomic::{AtomicBool, AtomicI32, AtomicU32, Ordering},
|
||||
};
|
||||
use system_error::SystemError;
|
||||
@ -295,36 +296,41 @@ pub struct TextuiCharChromatic {
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TextuiBuf<'a> {
|
||||
buf: Option<&'a mut [u32]>,
|
||||
guard: Option<SpinLockGuard<'a, Box<[u32]>>>,
|
||||
buf: Option<&'a mut [u8]>,
|
||||
|
||||
guard: Option<SpinLockGuard<'a, Box<[u8]>>>,
|
||||
|
||||
bit_depth: u32,
|
||||
}
|
||||
|
||||
impl TextuiBuf<'_> {
|
||||
pub fn new(buf: &mut ScmBufferInfo) -> TextuiBuf {
|
||||
let len = buf.buf_size() / 4;
|
||||
|
||||
let depth = video_refresh_manager().device_buffer().bit_depth();
|
||||
match &buf.buf {
|
||||
ScmBuffer::DeviceBuffer(vaddr) => {
|
||||
return TextuiBuf {
|
||||
buf: Some(unsafe {
|
||||
core::slice::from_raw_parts_mut(vaddr.data() as *mut u32, len)
|
||||
core::slice::from_raw_parts_mut(vaddr.data() as *mut u8, len)
|
||||
}),
|
||||
guard: None,
|
||||
bit_depth: depth,
|
||||
};
|
||||
}
|
||||
|
||||
ScmBuffer::DoubleBuffer(double_buffer) => {
|
||||
let guard: SpinLockGuard<'_, Box<[u32]>> = double_buffer.lock();
|
||||
let guard: SpinLockGuard<'_, Box<[u8]>> = double_buffer.lock();
|
||||
|
||||
return TextuiBuf {
|
||||
buf: None,
|
||||
guard: Some(guard),
|
||||
bit_depth: depth,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn buf_mut(&mut self) -> &mut [u32] {
|
||||
pub fn buf_mut(&mut self) -> &mut [u8] {
|
||||
if let Some(buf) = &mut self.buf {
|
||||
return buf;
|
||||
} else {
|
||||
@ -332,8 +338,34 @@ impl TextuiBuf<'_> {
|
||||
}
|
||||
}
|
||||
pub fn put_color_in_pixel(&mut self, color: u32, index: usize) {
|
||||
let buf: &mut [u32] = self.buf_mut();
|
||||
buf[index] = color;
|
||||
let index = index as isize;
|
||||
match self.bit_depth {
|
||||
32 => {
|
||||
let buf = self.buf_mut().as_mut_ptr() as *mut u32;
|
||||
unsafe {
|
||||
*buf.offset(index) = color;
|
||||
}
|
||||
}
|
||||
24 => {
|
||||
let buf = self.buf_mut().as_mut_ptr();
|
||||
unsafe {
|
||||
copy_nonoverlapping(&color as *const u32 as *const u8, buf.offset(index * 3), 3)
|
||||
};
|
||||
}
|
||||
16 => {
|
||||
let buf = self.buf_mut().as_mut_ptr();
|
||||
unsafe {
|
||||
copy_nonoverlapping(
|
||||
&color as *const u32 as *const u8,
|
||||
buf.offset(index * 2),
|
||||
2,
|
||||
);
|
||||
};
|
||||
}
|
||||
_ => {
|
||||
panic!("不支持的位深度!")
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn get_index_of_next_line(now_index: usize) -> usize {
|
||||
textui_framework().metadata.read().buf_info().width() as usize + now_index
|
||||
@ -430,8 +462,10 @@ impl TextuiCharChromatic {
|
||||
|
||||
let id_y: u32 = lineid.into();
|
||||
let y: u32 = id_y * TEXTUI_CHAR_HEIGHT;
|
||||
|
||||
let buf_depth = video_refresh_manager().device_buffer().bit_depth();
|
||||
let buf_width = video_refresh_manager().device_buffer().width();
|
||||
let byte_num_of_depth = (buf_depth / 8) as usize;
|
||||
|
||||
// 找到输入缓冲区的起始地址位置
|
||||
let buf_start =
|
||||
if let ScmBuffer::DeviceBuffer(vaddr) = video_refresh_manager().device_buffer().buf {
|
||||
@ -446,19 +480,35 @@ impl TextuiCharChromatic {
|
||||
for i in 0..TEXTUI_CHAR_HEIGHT {
|
||||
// 计算出帧缓冲区每一行打印的起始位置的地址(起始位置+(y+i)*缓冲区的宽度+x)
|
||||
|
||||
let mut addr: *mut u32 =
|
||||
(buf_start + buf_width as usize * 4 * (y as usize + i as usize) + 4 * x as usize)
|
||||
.data() as *mut u32;
|
||||
let mut addr: *mut u8 = (buf_start
|
||||
+ buf_width as usize * byte_num_of_depth * (y as usize + i as usize)
|
||||
+ byte_num_of_depth * x as usize)
|
||||
.data() as *mut u8;
|
||||
|
||||
testbit = 1 << (TEXTUI_CHAR_WIDTH + 1);
|
||||
|
||||
for _j in 0..TEXTUI_CHAR_WIDTH {
|
||||
//该循环是渲染一行像素
|
||||
//从左往右逐个测试相应位
|
||||
testbit >>= 1;
|
||||
if (font.0[i as usize] & testbit as u8) != 0 {
|
||||
unsafe { *addr = self.frcolor.into() }; // 字,显示前景色
|
||||
let color: u32 = self.frcolor.into();
|
||||
unsafe {
|
||||
copy_nonoverlapping(
|
||||
&color as *const u32 as *const u8,
|
||||
addr,
|
||||
byte_num_of_depth,
|
||||
)
|
||||
}; // 字,显示前景色
|
||||
} else {
|
||||
unsafe { *addr = self.bkcolor.into() }; // 背景色
|
||||
let color: u32 = self.bkcolor.into();
|
||||
unsafe {
|
||||
copy_nonoverlapping(
|
||||
&color as *const u32 as *const u8,
|
||||
addr,
|
||||
byte_num_of_depth,
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
unsafe {
|
||||
|
@ -36,7 +36,7 @@ pub fn no_init_textui_putchar_window(
|
||||
bkcolor: FontColor,
|
||||
is_put_to_window: bool,
|
||||
) -> Result<(), SystemError> {
|
||||
if NO_ALLOC_OPERATIONS_LINE.load(Ordering::SeqCst) > TRUE_LINE_NUM.load(Ordering::SeqCst) {
|
||||
if NO_ALLOC_OPERATIONS_LINE.load(Ordering::SeqCst) >= TRUE_LINE_NUM.load(Ordering::SeqCst) {
|
||||
NO_ALLOC_OPERATIONS_LINE.store(0, Ordering::SeqCst);
|
||||
}
|
||||
//字符'\0'代表ASCII码表中的空字符,表示字符串的结尾
|
||||
|
Reference in New Issue
Block a user