render_helper.rs 9.7 KB

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