Skip to main content

proka_kernel/graphics/
core.rs

1extern crate alloc;
2use crate::graphics::color;
3use crate::libs::bmp::{BmpError, BmpImage};
4use alloc::{vec, vec::Vec};
5use core::slice;
6use limine::framebuffer::Framebuffer;
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq)]
9pub struct Pixel {
10    pub x: u64,
11    pub y: u64,
12}
13
14impl Pixel {
15    pub fn new(x: u64, y: u64) -> Self {
16        Self { x, y }
17    }
18}
19
20pub trait PixelCoord {
21    fn to_coord(&self) -> (u64, u64);
22}
23
24impl PixelCoord for Pixel {
25    fn to_coord(&self) -> (u64, u64) {
26        (self.x, self.y)
27    }
28}
29
30#[macro_export]
31macro_rules! pixel {
32    ($x:expr, $y:expr) => {{
33        Pixel::new(($x) as u64, ($y) as u64)
34    }};
35}
36
37pub struct Renderer<'a> {
38    framebuffer: Framebuffer<'a>, // 前台缓冲区
39    back_buffer: Vec<u8>,         // 后台缓冲区
40    pixel_size: usize,            // 每个像素占用的字节数
41    clear_color: color::Color,    // 默认清屏颜色
42    dirty_min_x: u64,
43    dirty_min_y: u64,
44    dirty_max_x: u64,
45    dirty_max_y: u64,
46    width: usize,
47    height: usize,
48    bpp: usize,
49}
50
51impl<'a> Renderer<'a> {
52    pub fn new(framebuffer: Framebuffer<'a>) -> Self {
53        let width = framebuffer.width() as usize;
54        let height = framebuffer.height() as usize;
55        let bpp = framebuffer.bpp() as usize; // bits per pixel
56        let pixel_size = bpp / 8; // bytes per pixel
57        let buffer_size = width * height * pixel_size; // 后台缓冲区总字节数
58
59        // 初始化后台缓冲区,填充为0(黑色)
60        let back_buffer = vec![0; buffer_size];
61        Self {
62            framebuffer: framebuffer,
63            back_buffer,
64            pixel_size,
65            clear_color: color::BLACK,
66            dirty_min_x: u64::MAX,
67            dirty_min_y: u64::MAX,
68            dirty_max_x: 0,
69            dirty_max_y: 0,
70            width,
71            height,
72            bpp,
73        }
74    }
75
76    /// 获取后台缓冲区偏移
77    #[inline(always)]
78    fn get_buffer_offset(&self, x: u64, y: u64) -> usize {
79        // 后台缓冲区的布局是线性的,不一定与framebuffer的pitch相同
80        y as usize * self.framebuffer.width() as usize * self.pixel_size
81            + x as usize * self.pixel_size
82    }
83
84    /// 转换颜色为帧缓冲区格式
85    #[inline(always)]
86    fn mask_color(&self, color: &color::Color) -> u32 {
87        if self.bpp == 32 {
88            let value: u32 = ((color.r as u32) << self.framebuffer.red_mask_shift())
89                | ((color.g as u32) << self.framebuffer.green_mask_shift())
90                | ((color.b as u32) << self.framebuffer.blue_mask_shift());
91            return value;
92        } else if self.bpp == 24 {
93            color.to_u32(false)
94        } else {
95            panic!("Unsupported bit per pixel: {}", self.framebuffer.bpp())
96        }
97    }
98
99    /// 绘制像素到后台缓冲区
100    #[inline(always)]
101    pub unsafe fn set_pixel_raw_unchecked(&mut self, x: u64, y: u64, color: &color::Color) {
102        let offset = self.get_buffer_offset(x, y);
103
104        let color_u32 = if color.a == 255 {
105            self.mask_color(color)
106        } else if color.a == 0 {
107            return;
108        } else {
109            // 读取后台缓冲区当前像素颜色进行alpha混合
110            let current_color = self.get_pixel_raw(x, y);
111
112            // 执行alpha混合: result = (source * alpha + destination * (255 - alpha)) / 255
113            let alpha = color.a as u32;
114            let inv_alpha = 255 - alpha;
115            let r = (color.r as u32 * alpha + current_color.r as u32 * inv_alpha) / 255;
116            let g = (color.g as u32 * alpha + current_color.g as u32 * inv_alpha) / 255;
117            let b = (color.b as u32 * alpha + current_color.b as u32 * inv_alpha) / 255;
118
119            let mixed_color = color::Color::with_alpha(r as u8, g as u8, b as u8, 255);
120            self.mask_color(&mixed_color)
121        };
122
123        let pixel_bytes = color_u32.to_le_bytes(); // 转换为字节数组
124        unsafe {
125            let dst_ptr = self.back_buffer.as_mut_ptr().add(offset);
126            core::ptr::copy_nonoverlapping(pixel_bytes.as_ptr(), dst_ptr, self.pixel_size);
127        }
128
129        self.dirty_min_x = self.dirty_min_x.min(x);
130        self.dirty_min_y = self.dirty_min_y.min(y);
131        self.dirty_max_x = self.dirty_max_x.max(x);
132        self.dirty_max_y = self.dirty_max_y.max(y);
133    }
134
135    #[inline(always)]
136    pub fn set_pixel_raw(&mut self, x: u64, y: u64, color: &color::Color) {
137        // 边界检查:确保像素在屏幕范围内
138        if x >= self.width as u64 || y >= self.height as u64 {
139            return;
140        }
141        unsafe { self.set_pixel_raw_unchecked(x, y, color) };
142    }
143
144    /// 设置像素
145    #[inline(always)]
146    pub fn set_pixel(&mut self, pixel: Pixel, color: &color::Color) {
147        let (x, y) = pixel.to_coord();
148        self.set_pixel_raw(x, y, color);
149    }
150
151    /// 获取像素
152    pub fn get_pixel(&self, pixel: Pixel) -> color::Color {
153        let (x, y) = pixel.to_coord();
154        self.get_pixel_raw(x, y) // 从前台缓冲区获取
155    }
156
157    /// 获取像素
158    fn get_pixel_raw(&self, x: u64, y: u64) -> color::Color {
159        let offset = self.get_buffer_offset(x, y);
160        let mut pixel_data_u32 = 0u32;
161        for i in 0..self.pixel_size {
162            pixel_data_u32 |= (self.back_buffer[offset + i] as u32) << (i * 8);
163        }
164        color::Color::from_u32(pixel_data_u32)
165    }
166
167    pub fn set_clear_color(&mut self, color: color::Color) {
168        self.clear_color = color;
169    }
170
171    pub fn get_clear_color(&self) -> color::Color {
172        self.clear_color
173    }
174
175    // 清空后台缓冲区
176    pub fn clear(&mut self) {
177        let width = self.framebuffer.width();
178        let height = self.framebuffer.height();
179        let color = self.clear_color.clone();
180        // 优化清空操作:直接填充后台缓冲区
181        let masked_clear_color = self.mask_color(&color);
182        let pixel_bytes = masked_clear_color.to_le_bytes(); // 转换为字节数组
183        let bytes_to_fill = &pixel_bytes[..self.pixel_size];
184        for y in 0..height {
185            for x in 0..width {
186                let offset = self.get_buffer_offset(x, y);
187                for i in 0..self.pixel_size {
188                    self.back_buffer[offset + i] = bytes_to_fill[i];
189                }
190            }
191        }
192
193        self.dirty_min_x = 0;
194        self.dirty_min_y = 0;
195        self.dirty_max_x = width;
196        self.dirty_max_y = height;
197    }
198
199    /// 绘制线
200    pub fn draw_line(&mut self, p1: Pixel, p2: Pixel, color: color::Color) {
201        let dx_abs = ((p2.x as i64 - p1.x as i64).abs()) as u64;
202        let dy_abs = ((p2.y as i64 - p1.y as i64).abs()) as u64;
203        let steep = dy_abs > dx_abs;
204        let (mut x1, mut y1) = p1.to_coord();
205        let (mut x2, mut y2) = p2.to_coord();
206        if steep {
207            core::mem::swap(&mut x1, &mut y1);
208            core::mem::swap(&mut x2, &mut y2);
209        }
210        if x1 > x2 {
211            core::mem::swap(&mut x1, &mut x2);
212            core::mem::swap(&mut y1, &mut y2);
213        }
214        let dx = x2 - x1;
215        let dy = (y2 as i64 - y1 as i64).abs() as u64;
216        let mut error = (dx / 2) as i64;
217        let y_step = if y1 < y2 { 1 } else { -1 };
218        let mut y = y1 as i64;
219        for x in x1..=x2 {
220            if steep {
221                // 确保 y, x 坐标在帧缓冲区范围内
222                if y >= 0 && (y as u64) < self.framebuffer.width() && x < self.framebuffer.height()
223                {
224                    self.set_pixel_raw(y as u64, x, &color);
225                }
226            } else {
227                if x < self.framebuffer.width() && y >= 0 && (y as u64) < self.framebuffer.height()
228                {
229                    self.set_pixel_raw(x, y as u64, &color);
230                }
231            }
232            error -= dy as i64;
233            if error < 0 {
234                y += y_step;
235                error += dx as i64;
236            }
237        }
238    }
239
240    /// 绘制三角形
241    pub fn draw_triangle(&mut self, p1: Pixel, p2: Pixel, p3: Pixel, color: color::Color) {
242        self.draw_line(p1, p2, color);
243        self.draw_line(p2, p3, color);
244        self.draw_line(p3, p1, color);
245    }
246
247    /// 填充三角形
248    pub fn fill_triangle(&mut self, p1: Pixel, p2: Pixel, p3: Pixel, color: color::Color) {
249        let (x1, y1) = p1.to_coord();
250        let (x2, y2) = p2.to_coord();
251        let (x3, y3) = p3.to_coord();
252        // 定义3个变换后的 Pixel
253        let mut pts = [pixel!(x1, y1), pixel!(x2, y2), pixel!(x3, y3)];
254        // 按 y 轻量排序:冒泡排序也可以
255        for i in 0..pts.len() {
256            for j in i + 1..pts.len() {
257                if pts[i].y > pts[j].y {
258                    pts.swap(i, j);
259                }
260            }
261        }
262        let p1 = pts[0];
263        let p2 = pts[1];
264        let p3 = pts[2];
265        // 如果三点 y 相同,不画
266        if p1.y == p3.y {
267            return;
268        }
269        // 获取 u32 坐标
270        let (x1, y1) = (p1.x as i32, p1.y as i32);
271        let (x2, y2) = (p2.x as i32, p2.y as i32);
272        let (x3, y3) = (p3.x as i32, p3.y as i32);
273        // 水平线闭包填充函数
274        let mut fill_h_line = |start_x: i32, end_x: i32, y: i32| {
275            if y < 0 || y >= self.framebuffer.height() as i32 {
276                return;
277            }
278            let mut start_x = start_x.max(0);
279            let mut end_x = end_x.min(self.framebuffer.width() as i32 - 1);
280            if start_x > end_x {
281                core::mem::swap(&mut start_x, &mut end_x);
282            }
283            if start_x < 0 || end_x >= self.framebuffer.width() as i32 {
284                start_x = start_x.max(0);
285                end_x = end_x.min(self.framebuffer.width() as i32 - 1);
286                if start_x > end_x {
287                    return;
288                }
289            }
290            // 填充到后台缓冲区
291            for x in start_x..=end_x {
292                if x >= 0 {
293                    let pixel = pixel!(x, y);
294                    self.set_pixel(pixel, &color);
295                }
296            }
297        };
298        let long_dx = x3 - x1;
299        let long_dy = y3 - y1;
300        if long_dy != 0 {
301            // 上半部分三角形(p1 -> p2)
302            let upper_dx = x2 - x1;
303            let upper_dy = y2 - y1;
304            let y_start = y1;
305            let y_end = y2;
306            for y in y_start..=y_end {
307                let dy = y - y1;
308                let x_long = if long_dy != 0 {
309                    x1 + (long_dx * dy + long_dy / 2) / long_dy
310                } else {
311                    x1
312                };
313                let x_upper = if upper_dy != 0 {
314                    x1 + (upper_dx * dy + upper_dy / 2) / upper_dy
315                } else {
316                    x1
317                };
318                fill_h_line(x_long, x_upper, y);
319            }
320            // 下半部分三角形(p2 -> p3)
321            let lower_dx = x3 - x2;
322            let lower_dy = y3 - y2;
323            if lower_dy != 0 {
324                for y in y2..=y3 {
325                    let dy_long = y - y1;
326                    let dy_lower = y - y2;
327                    let x_long = if long_dy != 0 {
328                        x1 + (long_dx * dy_long + long_dy / 2) / long_dy
329                    } else {
330                        x1
331                    };
332                    let x_lower = if lower_dy != 0 {
333                        x2 + (lower_dx * dy_lower + lower_dy / 2) / lower_dy
334                    } else {
335                        x2
336                    };
337                    fill_h_line(x_long, x_lower, y);
338                }
339            }
340        }
341    }
342
343    pub fn width(&self) -> u64 {
344        self.framebuffer.width()
345    }
346
347    pub fn height(&self) -> u64 {
348        self.framebuffer.height()
349    }
350
351    /// 绘制矩形
352    pub fn draw_rect(&mut self, pixel: Pixel, width: u64, height: u64, color: color::Color) -> () {
353        let (x, y) = pixel.to_coord();
354        let x2 = x + width;
355        let y2 = y + height;
356        // 绘制到后台缓冲区
357        self.draw_line(pixel!(x, y), pixel!(x2, y), color);
358        self.draw_line(pixel!(x2, y), pixel!(x2, y2), color);
359        self.draw_line(pixel!(x2, y2), pixel!(x, y2), color);
360        self.draw_line(pixel!(x, y2), pixel!(x, y), color);
361    }
362
363    /// 填充矩形
364    pub fn fill_rect(&mut self, pixel: Pixel, width: u64, height: u64, color: color::Color) {
365        let (x_min, y_min) = pixel.to_coord();
366        let x_max = x_min + width;
367        let y_max = y_min + height;
368        let x_start = x_min.max(0);
369        let x_end = x_max.min(self.width() - 1);
370        let y_start = y_min.max(0);
371        let y_end = y_max.min(self.height() - 1);
372        for y in y_start..=y_end {
373            for x in x_start..=x_end {
374                self.set_pixel_raw(x, y, &color); // 绘制到后台缓冲区
375            }
376        }
377    }
378
379    /// 绘制任意多边形(轮廓)
380    pub fn draw_polygon(&mut self, points: &[Pixel], color: color::Color) {
381        if points.len() < 3 {
382            return; // 少于3个点无法构成多边形
383        }
384        // 连接所有点形成闭合多边形
385        for i in 0..points.len() {
386            let p1 = points[i];
387            let p2 = points[(i + 1) % points.len()]; // 最后一个点连接回第一个点
388            self.draw_line(p1, p2, color);
389        }
390    }
391    /// 填充任意凸多边形(扫描线算法)
392    pub fn fill_convex_polygon(&mut self, points: &[Pixel], color: color::Color) {
393        if points.len() < 3 {
394            return; // 少于3个点无法构成多边形
395        }
396        // 收集所有边的信息
397        let mut edges = Vec::new();
398        for i in 0..points.len() {
399            let p1 = points[i];
400            let p2 = points[(i + 1) % points.len()];
401            edges.push((p1, p2));
402        }
403        // 找到多边形的y范围
404        let min_y = edges.iter().map(|&(p, _)| p.y).min().unwrap_or(0);
405        let max_y = edges.iter().map(|&(p, _)| p.y).max().unwrap_or(0);
406        // 计算每一条边的x增量信息
407        let mut edge_info: Vec<(f64, f64, f64, f64)> = Vec::new();
408        for &(p1, p2) in &edges {
409            if p1.y != p2.y {
410                let y_start = p1.y.min(p2.y) as f64;
411                let y_end = p1.y.max(p2.y) as f64;
412                let x_start = if p1.y < p2.y {
413                    p1.x as f64
414                } else {
415                    p2.x as f64
416                };
417                let dx = (p2.x as f64 - p1.x as f64) / (p2.y as f64 - p1.y as f64);
418                edge_info.push((y_start, y_end, x_start, dx));
419            }
420        }
421        // 扫描线填充
422        for y in min_y..=max_y {
423            let mut intersections = Vec::new();
424
425            // 计算当前扫描线y与所有边的交点
426            for &(y_start, y_end, x_start, dx) in &edge_info {
427                if (y as f64) >= y_start && (y as f64) <= y_end {
428                    let x = x_start + (y as f64 - y_start) * dx;
429                    intersections.push(x);
430                }
431            }
432            // 交点排序
433            intersections.sort_by(|a, b| a.partial_cmp(b).expect("Float comparison failed"));
434            // 填充扫描线交点之间的区域
435            for i in (0..intersections.len()).step_by(2) {
436                if i + 1 >= intersections.len() {
437                    break;
438                }
439
440                let start_x = intersections[i].max(0.0).min(self.width() as f64 - 1.0) as u64;
441                let end_x = intersections[i + 1].max(0.0).min(self.width() as f64 - 1.0) as u64;
442
443                if start_x > end_x {
444                    continue;
445                }
446
447                for x in start_x..=end_x {
448                    self.set_pixel_raw(x, y, &color);
449                }
450            }
451        }
452    }
453    /// 填充任意多边形(使用奇偶规则)
454    pub fn fill_polygon(&mut self, points: &[Pixel], color: color::Color) {
455        if points.len() < 3 {
456            return;
457        }
458        // 找到多边形的y范围
459        let min_y = points.iter().map(|p| p.y).min().unwrap_or(0);
460        let max_y = points.iter().map(|p| p.y).max().unwrap_or(0);
461        // 收集所有边的信息
462        let mut edge_table = Vec::new();
463        for i in 0..points.len() {
464            let p1 = points[i];
465            let p2 = points[(i + 1) % points.len()];
466
467            if p1.y != p2.y {
468                let (start, end) = if p1.y < p2.y { (p1, p2) } else { (p2, p1) };
469                let dx = (end.x as f64 - start.x as f64) / (end.y as f64 - start.y as f64);
470                edge_table.push((start.y as f64, end.y as f64, start.x as f64, dx));
471            }
472        }
473        // 扫描线填充
474        for y in min_y..=max_y {
475            let mut intersections = Vec::new();
476
477            // 检查每条边是否与当前扫描线相交
478            for &(y_min, y_max, mut x, dx) in &edge_table {
479                if (y as f64) >= y_min && (y as f64) < y_max {
480                    if y as f64 > y_min {
481                        x += (y as f64 - y_min) * dx;
482                    }
483                    intersections.push(x);
484                }
485            }
486            // 交点排序
487            intersections.sort_by(|a, b| a.partial_cmp(b).expect("Float comparison failed"));
488            // 填充扫描线交点之间的区域(奇偶规则)
489            let mut inside = false;
490            for i in 0..intersections.len() {
491                if inside && i < intersections.len() {
492                    let start_x = intersections[i].max(0.0).min(self.width() as f64 - 1.0) as u64;
493
494                    // 确保不会越界访问
495                    if i + 1 < intersections.len() {
496                        let end_x =
497                            intersections[i + 1].max(0.0).min(self.width() as f64 - 1.0) as u64;
498
499                        if start_x <= end_x {
500                            for x in start_x..=end_x {
501                                self.set_pixel_raw(x, y, &color);
502                            }
503                        }
504                    } else {
505                        // 处理最后一个点
506                        let end_x = self.width().min(self.width() - 1);
507                        if start_x <= end_x {
508                            for x in start_x..=end_x {
509                                self.set_pixel_raw(x, y, &color);
510                            }
511                        }
512                    }
513                }
514                inside = !inside;
515            }
516        }
517    }
518
519    /// 绘制BMP图像
520    pub fn draw_bmp(&mut self, pos: Pixel, bmp: &BmpImage) {
521        let (x_start, y_start) = (pos.x, pos.y);
522
523        for y in 0..bmp.height() {
524            for x in 0..bmp.width() {
525                if let Some(color) = bmp.pixel(x, y) {
526                    self.set_pixel_raw(x_start + x as u64, y_start + y as u64, &color);
527                }
528            }
529        }
530    }
531    /// 绘制BMP图像 (带缩放)
532    pub fn draw_bmp_scaled(&mut self, pos: Pixel, bmp: &BmpImage, scale_x: f32, scale_y: f32) {
533        let scaled_width = (bmp.width() as f32 * scale_x) as u64;
534        let scaled_height = (bmp.height() as f32 * scale_y) as u64;
535
536        for y in 0..scaled_height {
537            for x in 0..scaled_width {
538                // 计算原始图像中的对应位置
539                let src_x = (x as f32 / scale_x) as u32;
540                let src_y = (y as f32 / scale_y) as u32;
541
542                if let Some(color) = bmp.pixel(src_x, src_y) {
543                    self.set_pixel_raw(pos.x + x, pos.y + y, &color);
544                }
545            }
546        }
547    }
548    /// 绘制BMP图像 (扭曲变形)
549    pub fn draw_bmp_distorted(&mut self, corners: [Pixel; 4], bmp: &BmpImage) {
550        // 计算包围盒
551        let min_x = corners.iter().map(|p| p.x).min().unwrap_or(0);
552        let max_x = corners.iter().map(|p| p.x).max().unwrap_or(0);
553        let min_y = corners.iter().map(|p| p.y).min().unwrap_or(0);
554        let max_y = corners.iter().map(|p| p.y).max().unwrap_or(0);
555
556        // 计算变换矩阵 (简化的双线性插值)
557        for y in min_y..=max_y {
558            for x in min_x..=max_x {
559                // 计算相对位置 (简化版,实际应该使用更精确的纹理映射)
560                let u = (x - min_x) as f32 / (max_x - min_x) as f32;
561                let v = (y - min_y) as f32 / (max_y - min_y) as f32;
562
563                let src_x = (u * bmp.width() as f32) as u32;
564                let src_y = (v * bmp.height() as f32) as u32;
565
566                if let Some(color) = bmp.pixel(src_x, src_y) {
567                    self.set_pixel_raw(x, y, &color);
568                }
569            }
570        }
571    }
572    /// 从字节加载并绘制BMP图像
573    pub fn draw_bmp_from_bytes(&mut self, pos: Pixel, data: &[u8]) -> Result<(), BmpError> {
574        let bmp = BmpImage::from_bytes(data)?;
575        self.draw_bmp(pos, &bmp);
576        Ok(())
577    }
578
579    /// 绘制圆形
580    pub fn draw_circle(&mut self, center: Pixel, radius: u64, color: color::Color) {
581        if radius == 0 {
582            return;
583        }
584
585        let (cx, cy) = center.to_coord();
586        let mut x = 0i64;
587        let mut y = radius as i64;
588        let mut d = 3 - 2 * radius as i64;
589
590        while x <= y {
591            // 绘制8个对称点
592            self.set_pixel_raw((cx as i64 + x) as u64, (cy as i64 + y) as u64, &color);
593            self.set_pixel_raw((cx as i64 + x) as u64, (cy as i64 - y) as u64, &color);
594            self.set_pixel_raw((cx as i64 - x) as u64, (cy as i64 + y) as u64, &color);
595            self.set_pixel_raw((cx as i64 - x) as u64, (cy as i64 - y) as u64, &color);
596            self.set_pixel_raw((cx as i64 + y) as u64, (cy as i64 + x) as u64, &color);
597            self.set_pixel_raw((cx as i64 + y) as u64, (cy as i64 - x) as u64, &color);
598            self.set_pixel_raw((cx as i64 - y) as u64, (cy as i64 + x) as u64, &color);
599            self.set_pixel_raw((cx as i64 - y) as u64, (cy as i64 - x) as u64, &color);
600
601            if d < 0 {
602                d = d + 4 * x + 6;
603            } else {
604                d = d + 4 * (x - y) + 10;
605                y -= 1;
606            }
607            x += 1;
608        }
609    }
610
611    pub fn scroll_y(&mut self, offset: i64) {
612        let width = self.framebuffer.width();
613        let height = self.framebuffer.height();
614        let pixel_size = self.pixel_size;
615        let row_bytes = width as usize * pixel_size;
616
617        if offset == 0 {
618            return;
619        }
620
621        let abs_offset = offset.unsigned_abs();
622        if abs_offset >= height {
623            self.clear();
624            return;
625        }
626
627        let move_rows = height - abs_offset;
628        let move_bytes = move_rows as usize * row_bytes;
629
630        if offset > 0 {
631            let src_start = 0;
632            let dest_start = abs_offset as usize * row_bytes;
633            self.back_buffer
634                .copy_within(src_start..move_bytes, dest_start);
635
636            let clear_color = self.clear_color;
637            let masked_color = self.mask_color(&clear_color);
638            let pixel_bytes = masked_color.to_le_bytes();
639            let bytes_to_fill = &pixel_bytes[..pixel_size];
640
641            let mut clear_row = vec![0u8; row_bytes];
642            for x in 0..width as usize {
643                for i in 0..pixel_size {
644                    clear_row[x * pixel_size + i] = bytes_to_fill[i];
645                }
646            }
647            for y in 0..abs_offset {
648                let off = y as usize * row_bytes;
649                self.back_buffer[off..off + row_bytes].copy_from_slice(&clear_row);
650            }
651        } else {
652            let src_start = abs_offset as usize * row_bytes;
653            let dest_start = 0;
654            self.back_buffer
655                .copy_within(src_start..(src_start + move_bytes), dest_start);
656
657            let clear_color = self.clear_color;
658            let masked_color = self.mask_color(&clear_color);
659            let pixel_bytes = masked_color.to_le_bytes();
660            let bytes_to_fill = &pixel_bytes[..pixel_size];
661
662            let mut clear_row = vec![0u8; row_bytes];
663            for x in 0..width as usize {
664                for i in 0..pixel_size {
665                    clear_row[x * pixel_size + i] = bytes_to_fill[i];
666                }
667            }
668            for y in move_rows..height {
669                let off = y as usize * row_bytes;
670                self.back_buffer[off..off + row_bytes].copy_from_slice(&clear_row);
671            }
672        }
673        self.dirty_min_x = 0;
674        self.dirty_min_y = 0;
675        self.dirty_max_x = width;
676        self.dirty_max_y = height;
677    }
678
679    /// 将后台缓冲区的内容复制到前台帧缓冲区,从而显示绘制结果。
680    pub fn present(&mut self) {
681        let fb_width = self.framebuffer.width();
682        let fb_height = self.framebuffer.height();
683
684        let min_x = self.dirty_min_x.min(fb_width);
685        let min_y = self.dirty_min_y.min(fb_height);
686        let max_x = self.dirty_max_x.min(fb_width);
687        let max_y = self.dirty_max_y.min(fb_height);
688
689        if min_x >= max_x || min_y >= max_y {
690            return;
691        }
692
693        let width = (max_x - min_x) as usize;
694        let pitch = self.framebuffer.pitch() as usize; // Framebuffer每行的字节数
695        let pixel_size = self.pixel_size; // 后台缓冲区每个像素的字节数
696
697        unsafe {
698            let front_buffer_addr = self.framebuffer.addr();
699            for y in min_y..max_y {
700                let back_buffer_offset = (y * fb_width + min_x) as usize * pixel_size;
701                let front_buffer_offset = y as usize * pitch + min_x as usize * pixel_size;
702
703                let source_slice = &self.back_buffer
704                    [back_buffer_offset..(back_buffer_offset + width * pixel_size)];
705
706                let dest_ptr = front_buffer_addr.add(front_buffer_offset);
707                let dest_slice = slice::from_raw_parts_mut(dest_ptr, width * pixel_size);
708
709                dest_slice.copy_from_slice(source_slice);
710            }
711        }
712
713        self.dirty_min_x = u64::MAX;
714        self.dirty_min_y = u64::MAX;
715        self.dirty_max_x = 0;
716        self.dirty_max_y = 0;
717    }
718}