|
@@ -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 {
|