1 use core::{ops::Add, slice::Iter}; 2 3 use crate::mm::VirtAddr; 4 5 use super::FbImage; 6 7 pub struct BitIter<'a> { 8 fgcolor: u32, 9 bkcolor: u32, 10 _color_pattern: EndianPattern, 11 _dst_pattern: EndianPattern, 12 src: Iter<'a, u8>, 13 read_mask: u8, 14 byte_per_pixel: u32, 15 buffer: u32, 16 current: u8, 17 left_byte: u32, 18 done: bool, 19 consumed_bit: u32, 20 image_width: u32, 21 } 22 23 impl<'a> BitIter<'a> { 24 pub fn new( 25 fgcolor: u32, 26 bkcolor: u32, 27 dst_pattern: EndianPattern, 28 color_pattern: EndianPattern, 29 byte_per_pixel: u32, 30 src: Iter<'a, u8>, 31 image_width: u32, 32 ) -> Self { 33 let mut fgcolor = fgcolor; 34 let mut bkcolor = bkcolor; 35 if dst_pattern != color_pattern { 36 fgcolor = Self::reverse(fgcolor, byte_per_pixel); 37 bkcolor = Self::reverse(bkcolor, byte_per_pixel); 38 } 39 40 let mut ans = Self { 41 fgcolor, 42 bkcolor, 43 _color_pattern: color_pattern, 44 _dst_pattern: dst_pattern, 45 src, 46 read_mask: 0b10000000, 47 byte_per_pixel, 48 buffer: 0, 49 current: 0, 50 left_byte: 0, 51 done: false, 52 consumed_bit: 0, 53 image_width, 54 }; 55 ans.current = *ans.src.next().unwrap(); 56 return ans; 57 } 58 59 fn reverse(num: u32, byte_per_pixel: u32) -> u32 { 60 let mask = 0x000000ff; 61 let mut ans = 0; 62 let mut num = num; 63 for _ in 0..3 { 64 ans |= mask & num; 65 ans <<= 8; 66 num >>= 8; 67 } 68 ans |= mask & num; 69 ans >>= (4 - byte_per_pixel) * 8; 70 return ans; 71 } 72 73 fn move_mask(&mut self) -> bool { 74 self.consumed_bit += 1; 75 self.read_mask >>= 1; 76 if self.read_mask == 0b000000000 { 77 self.read_mask = 0b10000000; 78 self.current = match self.src.next() { 79 Some(x) => *x, 80 None => { 81 return false; 82 } 83 }; 84 return true; 85 } else { 86 return true; 87 } 88 } 89 90 fn full_buffer(&mut self) -> Result<PixelLineStatus, PixelLineStatus> { 91 let same_endian = if self._dst_pattern == self._color_pattern { 92 1 93 } else { 94 -1 95 }; 96 let mut color = self.read_bit() << (self.left_byte << 3); 97 let mut buffer_pointer = if self._dst_pattern == self._color_pattern { 98 0 99 } else { 100 3 101 }; 102 let mask = 0x000000ff << ((self.byte_per_pixel - 1) << 3); 103 let mut temp; 104 // while buffer_pointer >= 0 && buffer_pointer <= 3 { 105 while (0..=3).contains(&buffer_pointer) { 106 if self.consumed_bit >= self.image_width { 107 self.consumed_bit = 0; 108 return Ok(PixelLineStatus::Full(self.buffer)); 109 } 110 temp = color & mask; 111 color <<= 8; 112 temp <<= (4 - self.byte_per_pixel) * 8; 113 temp >>= buffer_pointer * 8; 114 self.buffer |= temp; 115 buffer_pointer += same_endian; 116 self.left_byte += 1; 117 if self.left_byte >= self.byte_per_pixel { 118 self.left_byte = 0; 119 if !self.move_mask() { 120 return Err(PixelLineStatus::Full(self.buffer)); 121 } 122 color = self.read_bit(); 123 } 124 } 125 if self.consumed_bit >= self.image_width { 126 self.consumed_bit = 0; 127 return Ok(PixelLineStatus::Full(self.buffer)); 128 } 129 return Ok(PixelLineStatus::NotFull(self.buffer)); 130 } 131 132 fn read_bit(&self) -> u32 { 133 match self.read_mask & self.current { 134 0 => self.bkcolor, 135 _ => self.fgcolor, 136 } 137 } 138 } 139 140 impl Iterator for BitIter<'_> { 141 type Item = (u32, bool); 142 fn next(&mut self) -> Option<Self::Item> { 143 if self.done { 144 return None; 145 } 146 match self.full_buffer() { 147 Ok(x) => { 148 self.buffer = 0; 149 return Some(x.unwarp()); 150 } 151 Err(x) => { 152 self.done = true; 153 return Some(x.unwarp()); 154 } 155 } 156 } 157 } 158 #[derive(PartialEq, PartialOrd)] 159 pub enum EndianPattern { 160 Big, 161 Little, 162 } 163 164 pub enum PixelLineStatus { 165 Full(u32), 166 NotFull(u32), 167 } 168 169 impl PixelLineStatus { 170 pub fn unwarp(self) -> (u32, bool) { 171 match self { 172 PixelLineStatus::Full(x) => (x, true), 173 PixelLineStatus::NotFull(x) => (x, false), 174 } 175 } 176 } 177 178 /// # 结构功能 179 /// 安全的FrameBufferPointer 180 /// 使用该结构体访问FrameBuffer可以防止超出FrameBuffer区域的访问 181 /// 需要注意,使用该指针写入时,任何超出屏幕的写入都是无效的!即使仍然可以写入显存。 182 /// 此外由于FbImage中的x和y变量采用u32类型,所以并未考虑左越界和上越界的安全性(即Image.x<0或Image.y<0的情况) 183 /// ## 成员 184 /// 185 /// - "dst" : 显存base address,通常是0xffffa1003ff00000 186 /// - "limit" : 显存区域上界,可以通过公式计算:limit = dst + 分辨率高*分辨率宽*每个像素的**字节**数。也就是说任何对于显存的访问应该限制在[dst,limit)中 187 /// - "current" : 当前相对于start_offset的位移 188 /// - "start_offset" : 如果你要渲染某个Image,你可能不是总是从屏幕左上角(0,0)开始渲染,你可能从某个offset开始 189 /// - "start_xpos" : 表示你要渲染的Image的x位置的字节位置 190 /// - "current_xpos" : 当前渲染的x位置的字节位置 191 /// - "limit_xpos" : 最大的渲染x位置的字节位置。 例:假设系统的分辨率为640,位深为24,你需要渲染的Image的x坐标为200,那么start_xpos=200*3=600,current_xpos=200*3+当前行已经渲染像素数*3,limit_xpos=640*3 192 #[derive(Debug)] 193 pub struct FrameP { 194 dst: VirtAddr, 195 limit: VirtAddr, 196 current: usize, 197 start_offset: usize, 198 start_xpos: usize, 199 current_xpos: usize, 200 limit_xpos: usize, 201 } 202 203 impl FrameP { 204 pub fn new( 205 frame_height: usize, 206 frame_width: usize, 207 bitdepth: usize, 208 dst: VirtAddr, 209 image: &FbImage, 210 ) -> Self { 211 let byte_per_pixel = bitdepth / 8; 212 let limit = VirtAddr::new(frame_height * frame_width * byte_per_pixel) + dst; 213 Self { 214 dst, 215 limit, 216 current: 0, 217 start_offset: start_offset(image, bitdepth as u32, (frame_width * bitdepth / 8) as u32) 218 as usize, 219 start_xpos: image.x as usize * byte_per_pixel, 220 current_xpos: image.x as usize * byte_per_pixel, 221 limit_xpos: frame_width * byte_per_pixel, 222 } 223 } 224 225 /// # 函数功能 226 /// 写入某个数据并将指针增大 227 pub fn write<T>(&mut self, data: T) -> FramePointerStatus { 228 // 首先获取数据大小 229 let size = size_of::<T>(); 230 // 复制显存指针防止改变self的dst 231 let mut dst = self.dst; 232 233 // 你最终要写入的位置实际上是[dst+start_offset+current,dst+start_offset+current+size),所以我们要确定你写入的位置是否超过limit 234 if self.dst.data() + self.current + self.start_offset + size > self.limit.data() { 235 return FramePointerStatus::OutOfBuffer; 236 } 237 // 我们也不希望你的x超出屏幕右边,超出屏幕右边的部分会被忽略掉,因为如果写入显存会导致内存风险 238 else if self.current_xpos + size > self.limit_xpos { 239 return FramePointerStatus::OutOfScreen; 240 } 241 // 如果上面两个检查都通过了,我们就可以写入显存了 242 else { 243 // 这里是写入位置的实际虚拟地址 244 dst = dst.add(self.current + self.start_offset); 245 } 246 // 写入操作 247 unsafe { 248 *dst.as_ptr::<T>() = data; 249 } 250 // 写入后更新current和xpos 251 self.current += size; 252 self.current_xpos += size; 253 // 由于写入正常,我们返回正常的状态 254 return FramePointerStatus::Normal; 255 } 256 257 /// # 函数功能 258 /// 移动指针**至**某个offset 259 /// todo: 当前函数应当只用于换行,否则可能会导致安全性问题,即offset应该是每行像素的开头 260 pub fn move_with_offset(&mut self, offset: u32) { 261 self.current = offset as usize; 262 // let x_pos=self.current%self.limit_xpos; 263 // match x_pos{ 264 // n if n<self.start_xpos=>{ 265 // // send_to_default_serial8250_port(format!("Sended by function move_with_offset: Check if there is misusage of offset,the image.x is:{:?} while the xpos indicated by the offset is:{:?},current FP:{:?}\n",self.start_offset,x_pos,self).as_bytes()); 266 // } 267 // n if n>=self.limit_xpos=>{ 268 // // send_to_default_serial8250_port(format!("Sended by function move_with_offset: Check if there is misusage of offset,The offset:{:?} is so large that it would exceed the limit of frame buffer\n",offset).as_bytes()); 269 // } 270 // _=>{ 271 272 // } 273 // } 274 self.current_xpos = self.start_xpos; 275 } 276 } 277 278 pub enum FramePointerStatus { 279 /// 表示状态正常 280 Normal, 281 /// 超出屏幕,一直到换行时才应该恢复到正常状态 282 OutOfScreen, 283 /// 超出缓存,此时应当立即停止渲染 284 OutOfBuffer, 285 } 286 287 pub fn start_offset(image: &FbImage, bitdepth: u32, line_length: u32) -> u32 { 288 let x = image.x; 289 let y = image.y; 290 let mut bitstart = (y * line_length * 8) + (x * bitdepth); 291 let byte_per_pixel = core::mem::size_of::<u32>() as u32; 292 // 位转字节 293 bitstart /= 8; 294 295 // 对齐到像素字节大小 296 bitstart &= !(byte_per_pixel - 1); 297 return bitstart; 298 } 299