|
@@ -1,4 +1,5 @@
|
|
|
use alloc::{string::String, sync::Arc, vec::Vec};
|
|
|
+use render_helper::{FrameP, FramePointerStatus};
|
|
|
use system_error::SystemError;
|
|
|
|
|
|
use crate::{
|
|
@@ -69,22 +70,20 @@ pub trait FrameBuffer: FrameBufferInfo + FrameBufferOps + Device {
|
|
|
let bit_per_pixel = self.current_fb_var().bits_per_pixel;
|
|
|
|
|
|
// 计算图像在帧缓冲中的起始位
|
|
|
- let mut bitstart = (y * self.current_fb_fix().line_length * 8) + (x * bit_per_pixel);
|
|
|
+ let bitstart = (y * self.current_fb_fix().line_length * 8) + (x * bit_per_pixel);
|
|
|
let start_index = bitstart & (32 - 1);
|
|
|
let pitch_index = (self.current_fb_fix().line_length & (byte_per_pixel - 1)) * 8;
|
|
|
- // 位转字节
|
|
|
- bitstart /= 8;
|
|
|
-
|
|
|
- // 对齐到像素字节大小
|
|
|
- bitstart &= !(byte_per_pixel - 1);
|
|
|
-
|
|
|
- let dst1 = boot_param.screen_info.lfb_virt_base;
|
|
|
- if dst1.is_none() {
|
|
|
+ let dst2 = boot_param.screen_info.lfb_virt_base;
|
|
|
+ if dst2.is_none() {
|
|
|
return;
|
|
|
}
|
|
|
- let mut dst1 = dst1.unwrap();
|
|
|
- dst1 += VirtAddr::new(bitstart as usize);
|
|
|
-
|
|
|
+ let mut safe_pointer = FrameP::new(
|
|
|
+ self.current_fb_var().yres as usize,
|
|
|
+ self.current_fb_var().xres as usize,
|
|
|
+ self.current_fb_var().bits_per_pixel as usize,
|
|
|
+ dst2.unwrap(),
|
|
|
+ image,
|
|
|
+ );
|
|
|
let _ = self.fb_sync();
|
|
|
|
|
|
if image.depth == 1 {
|
|
@@ -107,16 +106,9 @@ pub trait FrameBuffer: FrameBufferInfo + FrameBufferOps + Device {
|
|
|
&& image.width & (32 / bit_per_pixel - 1) == 0
|
|
|
&& (8..=32).contains(&bit_per_pixel)
|
|
|
{
|
|
|
- unsafe { self.fast_imageblit(image, dst1, fg, bg) }
|
|
|
+ unsafe { self.fast_imageblit(image, &mut safe_pointer, fg, bg) }
|
|
|
} else {
|
|
|
- self.slow_imageblit(
|
|
|
- image,
|
|
|
- dst1,
|
|
|
- fg,
|
|
|
- bg,
|
|
|
- bitstart / 4,
|
|
|
- self.current_fb_fix().line_length,
|
|
|
- )
|
|
|
+ self.slow_imageblit(image, &mut safe_pointer, fg, bg)
|
|
|
}
|
|
|
} else {
|
|
|
todo!("color image blit todo");
|
|
@@ -129,7 +121,7 @@ pub trait FrameBuffer: FrameBufferInfo + FrameBufferOps + Device {
|
|
|
/// 要求 image->width 可以被像素或 dword (ppw) 整除。
|
|
|
/// 要求 fix->line_length 可以被 4 整除。
|
|
|
/// 扫描线的开始和结束都是 dword 对齐的。
|
|
|
- unsafe fn fast_imageblit(&self, image: &FbImage, mut dst1: VirtAddr, fg: u32, bg: u32) {
|
|
|
+ unsafe fn fast_imageblit(&self, image: &FbImage, dst1: &mut FrameP, fg: u32, bg: u32) {
|
|
|
let bpp = self.current_fb_var().bits_per_pixel;
|
|
|
let mut fgx = fg;
|
|
|
let mut bgx = bg;
|
|
@@ -161,13 +153,12 @@ pub trait FrameBuffer: FrameBufferInfo + FrameBufferOps + Device {
|
|
|
color_tab[idx] = (*val & eorx) ^ bgx;
|
|
|
}
|
|
|
|
|
|
- let mut dst;
|
|
|
let mut shift;
|
|
|
let mut src;
|
|
|
let mut offset = 0;
|
|
|
let mut j = 0;
|
|
|
+ let mut count = 0;
|
|
|
for _ in (0..image.height).rev() {
|
|
|
- dst = dst1.as_ptr::<u32>();
|
|
|
shift = 8;
|
|
|
src = offset;
|
|
|
match ppw {
|
|
@@ -175,10 +166,8 @@ pub trait FrameBuffer: FrameBufferInfo + FrameBufferOps + Device {
|
|
|
// 8bpp
|
|
|
j = k;
|
|
|
while j >= 2 {
|
|
|
- *dst = color_tab[(image.data[src] as usize >> 4) & bitmask];
|
|
|
- dst = dst.add(1);
|
|
|
- *dst = color_tab[(image.data[src] as usize) & bitmask];
|
|
|
- dst = dst.add(1);
|
|
|
+ dst1.write(color_tab[(image.data[src] as usize >> 4) & bitmask]);
|
|
|
+ dst1.write(color_tab[(image.data[src] as usize) & bitmask]);
|
|
|
j -= 2;
|
|
|
src += 1;
|
|
|
}
|
|
@@ -187,14 +176,10 @@ pub trait FrameBuffer: FrameBufferInfo + FrameBufferOps + Device {
|
|
|
// 16bpp
|
|
|
j = k;
|
|
|
while j >= 4 {
|
|
|
- *dst = color_tab[(image.data[src] as usize >> 6) & bitmask];
|
|
|
- dst = dst.add(1);
|
|
|
- *dst = color_tab[(image.data[src] as usize >> 4) & bitmask];
|
|
|
- dst = dst.add(1);
|
|
|
- *dst = color_tab[(image.data[src] as usize >> 2) & bitmask];
|
|
|
- dst = dst.add(1);
|
|
|
- *dst = color_tab[(image.data[src] as usize) & bitmask];
|
|
|
- dst = dst.add(1);
|
|
|
+ dst1.write(color_tab[(image.data[src] as usize >> 6) & bitmask]);
|
|
|
+ dst1.write(color_tab[(image.data[src] as usize >> 4) & bitmask]);
|
|
|
+ dst1.write(color_tab[(image.data[src] as usize >> 2) & bitmask]);
|
|
|
+ dst1.write(color_tab[(image.data[src] as usize) & bitmask]);
|
|
|
src += 1;
|
|
|
j -= 4;
|
|
|
}
|
|
@@ -203,22 +188,14 @@ pub trait FrameBuffer: FrameBufferInfo + FrameBufferOps + Device {
|
|
|
// 32 bpp
|
|
|
j = k;
|
|
|
while j >= 8 {
|
|
|
- *dst = color_tab[(image.data[src] as usize >> 7) & bitmask];
|
|
|
- dst = dst.add(1);
|
|
|
- *dst = color_tab[(image.data[src] as usize >> 6) & bitmask];
|
|
|
- dst = dst.add(1);
|
|
|
- *dst = color_tab[(image.data[src] as usize >> 5) & bitmask];
|
|
|
- dst = dst.add(1);
|
|
|
- *dst = color_tab[(image.data[src] as usize >> 4) & bitmask];
|
|
|
- dst = dst.add(1);
|
|
|
- *dst = color_tab[(image.data[src] as usize >> 3) & bitmask];
|
|
|
- dst = dst.add(1);
|
|
|
- *dst = color_tab[(image.data[src] as usize >> 2) & bitmask];
|
|
|
- dst = dst.add(1);
|
|
|
- *dst = color_tab[(image.data[src] as usize >> 1) & bitmask];
|
|
|
- dst = dst.add(1);
|
|
|
- *dst = color_tab[(image.data[src] as usize) & bitmask];
|
|
|
- dst = dst.add(1);
|
|
|
+ dst1.write(color_tab[(image.data[src] as usize >> 7) & bitmask]);
|
|
|
+ dst1.write(color_tab[(image.data[src] as usize >> 6) & bitmask]);
|
|
|
+ dst1.write(color_tab[(image.data[src] as usize >> 5) & bitmask]);
|
|
|
+ dst1.write(color_tab[(image.data[src] as usize >> 4) & bitmask]);
|
|
|
+ dst1.write(color_tab[(image.data[src] as usize >> 3) & bitmask]);
|
|
|
+ dst1.write(color_tab[(image.data[src] as usize >> 2) & bitmask]);
|
|
|
+ dst1.write(color_tab[(image.data[src] as usize >> 1) & bitmask]);
|
|
|
+ dst1.write(color_tab[(image.data[src] as usize) & bitmask]);
|
|
|
src += 1;
|
|
|
j -= 8;
|
|
|
}
|
|
@@ -233,8 +210,7 @@ pub trait FrameBuffer: FrameBufferInfo + FrameBufferOps + Device {
|
|
|
*/
|
|
|
while j != 0 {
|
|
|
shift -= ppw;
|
|
|
- *dst = color_tab[(image.data[src] as usize >> shift) & bitmask];
|
|
|
- dst = dst.add(1);
|
|
|
+ dst1.write(color_tab[(image.data[src] as usize >> shift) & bitmask]);
|
|
|
if shift == 0 {
|
|
|
shift = 8;
|
|
|
src += 1;
|
|
@@ -242,22 +218,15 @@ pub trait FrameBuffer: FrameBufferInfo + FrameBufferOps + Device {
|
|
|
j -= 1;
|
|
|
}
|
|
|
|
|
|
- dst1 += VirtAddr::new(self.current_fb_fix().line_length as usize);
|
|
|
+ count += 1;
|
|
|
+ dst1.move_with_offset(self.current_fb_fix().line_length * count);
|
|
|
offset += spitch as usize;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- fn slow_imageblit(
|
|
|
- &self,
|
|
|
- _image: &FbImage,
|
|
|
- _dst1: VirtAddr,
|
|
|
- _fg: u32,
|
|
|
- _bg: u32,
|
|
|
- _start_index: u32,
|
|
|
- _pitch_index: u32,
|
|
|
- ) {
|
|
|
- let mut dst = _dst1.as_ptr::<u32>();
|
|
|
+ fn slow_imageblit(&self, _image: &FbImage, safe_dst: &mut FrameP, _fg: u32, _bg: u32) {
|
|
|
let mut count = 0;
|
|
|
+ let mut pt_status = FramePointerStatus::Normal;
|
|
|
let iter = BitIter::new(
|
|
|
_fg,
|
|
|
_bg,
|
|
@@ -268,17 +237,19 @@ pub trait FrameBuffer: FrameBufferInfo + FrameBufferOps + Device {
|
|
|
_image.width,
|
|
|
);
|
|
|
for (content, full) in iter {
|
|
|
- unsafe {
|
|
|
- *dst = content;
|
|
|
-
|
|
|
- dst = dst.add(1);
|
|
|
+ match pt_status {
|
|
|
+ FramePointerStatus::OutOfBuffer => {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ FramePointerStatus::OutOfScreen => {}
|
|
|
+ FramePointerStatus::Normal => {
|
|
|
+ pt_status = safe_dst.write(content);
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
if full {
|
|
|
count += 1;
|
|
|
- dst = unsafe {
|
|
|
- _dst1.as_ptr::<u8>().add((_pitch_index * count) as usize) as *mut u32
|
|
|
- };
|
|
|
+ safe_dst.move_with_offset(self.current_fb_fix().line_length * count);
|
|
|
+ pt_status = FramePointerStatus::Normal;
|
|
|
}
|
|
|
}
|
|
|
}
|