xref: /DragonOS/kernel/src/driver/video/fbdev/base/mod.rs (revision 9e481b3bfe303e0b104694da9750ae978dfeecae)
1 use alloc::{string::String, sync::Arc, vec::Vec};
2 use system_error::SystemError;
3 
4 use crate::{
5     driver::{base::device::Device, tty::virtual_terminal::Color},
6     init::boot_params,
7     libs::rwlock::RwLock,
8     mm::{ucontext::LockedVMA, PhysAddr, VirtAddr},
9 };
10 
11 use self::fbmem::{FbDevice, FrameBufferManager};
12 
13 const COLOR_TABLE_8: &'static [u32] = &[
14     0x00000000, 0xff000000, 0x00ff0000, 0xffff0000, 0x0000ff00, 0xff00ff00, 0x00ffff00, 0xffffff00,
15     0x000000ff, 0xff0000ff, 0x00ff00ff, 0xffff00ff, 0x0000ffff, 0xff00ffff, 0x00ffffff, 0xffffffff,
16 ];
17 
18 const COLOR_TABLE_16: &'static [u32] = &[0x00000000, 0xffff0000, 0x0000ffff, 0xffffffff];
19 
20 const COLOR_TABLE_32: &'static [u32] = &[0x00000000, 0xffffffff];
21 
22 pub mod fbcon;
23 pub mod fbmem;
24 pub mod fbsysfs;
25 pub mod modedb;
26 
27 // 帧缓冲区id
28 int_like!(FbId, u32);
29 
30 lazy_static! {
31     pub static ref FRAME_BUFFER_SET: RwLock<Vec<Option<Arc<dyn FrameBuffer>>>> = {
32         let mut ret = Vec::new();
33         ret.resize(FrameBufferManager::FB_MAX, None);
34         RwLock::new(ret)
35     };
36 }
37 
38 impl FbId {
39     /// 帧缓冲区id的初始值(无效值)
40     pub const INIT: Self = Self::new(u32::MAX);
41 
42     /// 判断是否为无效的帧缓冲区id
43     #[allow(dead_code)]
44     pub const fn is_valid(&self) -> bool {
45         if self.0 == Self::INIT.0 || self.0 >= FrameBufferManager::FB_MAX as u32 {
46             return false;
47         }
48         return true;
49     }
50 }
51 
52 /// 帧缓冲区应该实现的接口
53 pub trait FrameBuffer: FrameBufferInfo + FrameBufferOps + Device {
54     /// 获取帧缓冲区的id
55     fn fb_id(&self) -> FbId;
56 
57     /// 设置帧缓冲区的id
58     fn set_fb_id(&self, id: FbId);
59 
60     /// 通用的软件图像绘画
61     fn generic_imageblit(&self, image: &FbImage) {
62         let boot_param = boot_params().read();
63         let x = image.x;
64         let y = image.y;
65         let byte_per_pixel = core::mem::size_of::<u32>() as u32;
66         let bit_per_pixel = self.current_fb_var().bits_per_pixel;
67 
68         // 计算图像在帧缓冲中的起始位
69         let mut bitstart = (y * self.current_fb_fix().line_length * 8) + (x * bit_per_pixel);
70         let start_index = bitstart & (32 - 1);
71         let pitch_index = (self.current_fb_fix().line_length & (byte_per_pixel - 1)) * 8;
72         // 位转字节
73         bitstart /= 8;
74 
75         // 对齐到像素字节大小
76         bitstart &= !(byte_per_pixel - 1);
77 
78         let dst1 = boot_param.screen_info.lfb_virt_base;
79         if dst1.is_none() {
80             return;
81         }
82         let mut dst1 = dst1.unwrap();
83         dst1 = dst1 + VirtAddr::new(bitstart as usize);
84 
85         let _ = self.fb_sync();
86 
87         if image.depth == 1 {
88             let fg;
89             let bg;
90             if self.current_fb_fix().visual == FbVisual::TrueColor
91                 || self.current_fb_fix().visual == FbVisual::DirectColor
92             {
93                 let fb_info_data = self.framebuffer_info_data().read();
94                 fg = fb_info_data.pesudo_palette[image.fg as usize];
95                 bg = fb_info_data.pesudo_palette[image.bg as usize];
96             } else {
97                 fg = image.fg;
98                 bg = image.bg;
99             }
100 
101             if 32 % bit_per_pixel == 0
102                 && start_index == 0
103                 && pitch_index == 0
104                 && image.width & (32 / bit_per_pixel - 1) == 0
105                 && bit_per_pixel >= 8
106                 && bit_per_pixel <= 32
107             {
108                 unsafe { self.fast_imageblit(image, dst1, fg, bg) }
109             } else {
110                 self.slow_imageblit(image, dst1, fg, bg, start_index, pitch_index)
111             }
112         } else {
113             todo!("color image blit todo");
114         }
115     }
116 
117     /// 优化的单色图像绘制函数
118     ///
119     /// 仅当 bits_per_pixel 为 8、16 或 32 时才能使用。
120     /// 要求 image->width 可以被像素或 dword (ppw) 整除。
121     /// 要求 fix->line_length 可以被 4 整除。
122     /// 扫描线的开始和结束都是 dword 对齐的。
123     unsafe fn fast_imageblit(&self, image: &FbImage, mut dst1: VirtAddr, fg: u32, bg: u32) {
124         let bpp = self.current_fb_var().bits_per_pixel;
125         let mut fgx = fg;
126         let mut bgx = bg;
127         let ppw = 32 / bpp;
128         let spitch = (image.width + 7) / 8;
129         let tab: &[u32];
130         let mut color_tab: [u32; 16] = [0; 16];
131 
132         match bpp {
133             8 => {
134                 tab = COLOR_TABLE_8;
135             }
136             16 => {
137                 tab = COLOR_TABLE_16;
138             }
139             32 => {
140                 tab = COLOR_TABLE_32;
141             }
142             _ => {
143                 return;
144             }
145         }
146 
147         for _ in (0..(ppw - 1)).rev() {
148             fgx <<= bpp;
149             bgx <<= bpp;
150             fgx |= fg;
151             bgx |= bg;
152         }
153 
154         let bitmask = (1 << ppw) - 1;
155         let eorx = fgx ^ bgx;
156         let k = image.width / ppw;
157 
158         for (idx, val) in tab.iter().enumerate() {
159             color_tab[idx] = (*val & eorx) ^ bgx;
160         }
161 
162         let mut dst;
163         let mut shift;
164         let mut src;
165         let mut offset = 0;
166         let mut j = 0;
167         for _ in (0..image.height).rev() {
168             dst = dst1.as_ptr::<u32>();
169             shift = 8;
170             src = offset;
171             match ppw {
172                 4 => {
173                     // 8bpp
174                     j = k;
175                     while j >= 2 {
176                         *dst = color_tab[(image.data[src] as usize >> 4) & bitmask];
177                         dst = dst.add(1);
178                         *dst = color_tab[(image.data[src] as usize >> 0) & bitmask];
179                         dst = dst.add(1);
180                         j -= 2;
181                         src += 1;
182                     }
183                 }
184                 2 => {
185                     // 16bpp
186                     j = k;
187                     while j >= 4 {
188                         *dst = color_tab[(image.data[src] as usize >> 6) & bitmask];
189                         dst = dst.add(1);
190                         *dst = color_tab[(image.data[src] as usize >> 4) & bitmask];
191                         dst = dst.add(1);
192                         *dst = color_tab[(image.data[src] as usize >> 2) & bitmask];
193                         dst = dst.add(1);
194                         *dst = color_tab[(image.data[src] as usize >> 0) & bitmask];
195                         dst = dst.add(1);
196                         src += 1;
197                         j -= 4;
198                     }
199                 }
200                 1 => {
201                     // 32 bpp
202                     j = k;
203                     while j >= 8 {
204                         *dst = color_tab[(image.data[src] as usize >> 7) & bitmask];
205                         dst = dst.add(1);
206                         *dst = color_tab[(image.data[src] as usize >> 6) & bitmask];
207                         dst = dst.add(1);
208                         *dst = color_tab[(image.data[src] as usize >> 5) & bitmask];
209                         dst = dst.add(1);
210                         *dst = color_tab[(image.data[src] as usize >> 4) & bitmask];
211                         dst = dst.add(1);
212                         *dst = color_tab[(image.data[src] as usize >> 3) & bitmask];
213                         dst = dst.add(1);
214                         *dst = color_tab[(image.data[src] as usize >> 2) & bitmask];
215                         dst = dst.add(1);
216                         *dst = color_tab[(image.data[src] as usize >> 1) & bitmask];
217                         dst = dst.add(1);
218                         *dst = color_tab[(image.data[src] as usize >> 0) & bitmask];
219                         dst = dst.add(1);
220                         src += 1;
221                         j -= 8;
222                     }
223                 }
224                 _ => {}
225             }
226 
227             while j != 0 {
228                 shift -= ppw;
229                 *dst = color_tab[(image.data[src] as usize >> shift) & bitmask];
230                 dst = dst.add(1);
231                 if shift == 0 {
232                     shift = 8;
233                     src += 1;
234                 }
235             }
236 
237             dst1 += VirtAddr::new(self.current_fb_fix().line_length as usize);
238             offset += spitch as usize;
239         }
240     }
241 
242     fn slow_imageblit(
243         &self,
244         _image: &FbImage,
245         _dst1: VirtAddr,
246         _fg: u32,
247         _bg: u32,
248         _start_index: u32,
249         _pitch_index: u32,
250     ) {
251         todo!();
252         // let bpp = self.current_fb_var().bits_per_pixel;
253         // let pitch = self.current_fb_fix().line_length;
254         // let null_bits = 32 - bpp;
255         // let spitch = (image.width + 7) / 8;
256 
257         // // TODO:这里是需要计算的,但是目前用不到,先直接写
258         // let bswapmask = 0;
259 
260         // let dst2 = dst1;
261 
262         // // 一行一行画
263         // for i in image.height..0 {
264         //     let dst = dst1;
265 
266         //     if start_index > 0 {
267         //         let start_mask = !(!(0 as u32) << start_index);
268         //     }
269         // }
270     }
271 }
272 
273 #[derive(Debug, Default)]
274 pub struct FrameBufferInfoData {
275     /// 颜色映射
276     pub color_map: Vec<Color>,
277     /// 颜色映射表
278     pub pesudo_palette: Vec<u32>,
279 }
280 
281 impl FrameBufferInfoData {
282     pub fn new() -> Self {
283         Self {
284             ..Default::default()
285         }
286     }
287 }
288 
289 /// 帧缓冲区信息
290 pub trait FrameBufferInfo: FrameBufferOps {
291     fn framebuffer_info_data(&self) -> &RwLock<FrameBufferInfoData>;
292 
293     /// Amount of ioremapped VRAM or 0
294     fn screen_size(&self) -> usize;
295 
296     /// 获取当前的可变帧缓冲信息
297     fn current_fb_var(&self) -> FbVarScreenInfo;
298 
299     /// 获取当前的固定帧缓冲信息
300     fn current_fb_fix(&self) -> FixedScreenInfo;
301 
302     /// 获取当前的视频模式
303     fn video_mode(&self) -> Option<&FbVideoMode>;
304 
305     /// 获取当前帧缓冲区对应的`/sys/class/graphics/fb0`或者`/sys/class/graphics/fb1`等的设备结构体
306     fn fb_device(&self) -> Option<Arc<FbDevice>>;
307 
308     /// 设置当前帧缓冲区对应的`/sys/class/graphics/fb0`或者`/sys/class/graphics/fb1`等的设备结构体
309     fn set_fb_device(&self, device: Option<Arc<FbDevice>>);
310 
311     /// 获取帧缓冲区的状态
312     fn state(&self) -> FbState;
313 
314     /// 颜色位深
315     fn color_depth(&self) -> u32 {
316         return 8;
317 
318         // 以下逻辑没问题,但是当前没有初始化好var,所以先直接返回当前vasafb的8
319 
320         // let var = self.current_fb_var();
321         // let fix = self.current_fb_fix();
322         // if fix.visual == FbVisual::Mono01 || fix.visual == FbVisual::Mono10 {
323         //     return 1;
324         // } else {
325         //     if var.green.length == var.blue.length
326         //         && var.green.length == var.red.length
327         //         && var.green.offset == var.blue.offset
328         //         && var.green.offset == var.red.offset
329         //     {
330         //         kerror!("return {}", var.green.length);
331         //         return var.green.length;
332         //     } else {
333         //         return var.green.length + var.blue.length + var.red.length;
334         //     }
335         // }
336     }
337 
338     /// ## 设置调色板
339     fn set_color_map(&self, cmap: Vec<Color>) -> Result<(), SystemError> {
340         let ret = self.fb_set_color_map(cmap.clone());
341         if ret.is_err() && ret.clone().unwrap_err() == SystemError::ENOSYS {
342             for (idx, color) in cmap.iter().enumerate() {
343                 if self
344                     .fb_set_color_register(idx as u16, color.red, color.green, color.blue)
345                     .is_err()
346                 {
347                     break;
348                 }
349             }
350 
351             self.framebuffer_info_data().write().color_map = cmap;
352         } else {
353             if ret.is_ok() {
354                 self.framebuffer_info_data().write().color_map = cmap;
355             }
356             return ret;
357         }
358 
359         Ok(())
360     }
361 }
362 
363 /// 帧缓冲区操作
364 ///
365 /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/fb.h#237
366 pub trait FrameBufferOps {
367     fn fb_open(&self, user: bool);
368     fn fb_release(&self, user: bool);
369 
370     /// 读取帧缓冲区的内容。
371     ///
372     /// 对于具有奇特非线性布局的帧缓冲区或正常内存映射访问无法工作的帧缓冲区,可以使用此方法。
373     fn fb_read(&self, _buf: &mut [u8], _pos: usize) -> Result<usize, SystemError> {
374         Err(SystemError::ENOSYS)
375     }
376 
377     /// 将帧缓冲区的内容写入。
378     ///
379     /// 对于具有奇特非线性布局的帧缓冲区或正常内存映射访问无法工作的帧缓冲区,可以使用此方法。
380     fn fb_write(&self, _buf: &[u8], _pos: usize) -> Result<usize, SystemError> {
381         Err(SystemError::ENOSYS)
382     }
383 
384     /// 设置帧缓冲区的颜色寄存器。
385     ///
386     /// 颜色寄存器的数量和含义取决于帧缓冲区的硬件。
387     ///
388     /// ## 参数
389     ///
390     /// - `regno`:寄存器编号。
391     /// - `red`:红色分量。
392     /// - `green`:绿色分量。
393     /// - `blue`:蓝色分量。
394     fn fb_set_color_register(
395         &self,
396         regno: u16,
397         red: u16,
398         green: u16,
399         blue: u16,
400     ) -> Result<(), SystemError>;
401 
402     /// 设置帧缓冲区的黑屏模式
403     fn fb_blank(&self, blank_mode: BlankMode) -> Result<(), SystemError>;
404 
405     /// 在帧缓冲区中绘制一个矩形。
406     fn fb_fillrect(&self, _data: FillRectData) -> Result<(), SystemError> {
407         Err(SystemError::ENOSYS)
408     }
409 
410     /// 将数据从一处复制到另一处。
411     fn fb_copyarea(&self, _data: CopyAreaData);
412 
413     /// 将帧缓冲区的内容映射到用户空间。
414     fn fb_mmap(&self, _vma: &Arc<LockedVMA>) -> Result<(), SystemError> {
415         Err(SystemError::ENOSYS)
416     }
417 
418     /// 卸载与该帧缓冲区相关的所有资源
419     fn fb_destroy(&self);
420 
421     /// 画光标
422     fn fb_cursor(&self, _cursor: &FbCursor) -> Result<(), SystemError> {
423         return Err(SystemError::ENOSYS);
424     }
425 
426     /// 画软光标(暂时简要实现)
427     fn soft_cursor(&self, cursor: FbCursor) -> Result<(), SystemError> {
428         let mut image = cursor.image.clone();
429         if cursor.enable {
430             match cursor.rop {
431                 true => {
432                     for i in 0..image.data.len() {
433                         image.data[i] ^= cursor.mask[i];
434                     }
435                 }
436                 false => {
437                     for i in 0..image.data.len() {
438                         image.data[i] &= cursor.mask[i];
439                     }
440                 }
441             }
442         }
443 
444         let _ = self.fb_image_blit(&image);
445 
446         Ok(())
447     }
448 
449     fn fb_sync(&self) -> Result<(), SystemError> {
450         return Err(SystemError::ENOSYS);
451     }
452 
453     /// 绘画位图
454     fn fb_image_blit(&self, image: &FbImage);
455 
456     fn fb_set_color_map(&self, _cmap: Vec<Color>) -> Result<(), SystemError> {
457         return Err(SystemError::ENOSYS);
458     }
459 }
460 
461 /// 帧缓冲区的状态
462 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
463 pub enum FbState {
464     Running = 0,
465     Suspended = 1,
466 }
467 
468 /// 屏幕黑屏模式。
469 #[allow(dead_code)]
470 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
471 pub enum BlankMode {
472     /// 取消屏幕黑屏, 垂直同步和水平同步均打开
473     Unblank,
474     /// 屏幕黑屏, 垂直同步和水平同步均打开
475     Normal,
476     /// 屏幕黑屏, 水平同步打开, 垂直同步关闭
477     HSync,
478     /// 屏幕黑屏, 水平同步关闭, 垂直同步打开
479     VSync,
480     /// 屏幕黑屏, 水平同步和垂直同步均关闭
481     Powerdown,
482 }
483 
484 /// `FillRectData` 结构体用于表示一个矩形区域并填充特定颜色。
485 ///
486 /// # 结构体字段
487 /// * `dx`:
488 /// * `dy`:
489 /// * `width`:
490 /// * `height`: 矩形的高度
491 /// * `color`: 用于填充矩形的颜色,是一个32位无符号整数
492 /// * `rop`: 光栅操作(Raster Operation),用于定义如何将颜色应用到矩形区域
493 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
494 pub struct FillRectData {
495     /// 矩形左上角的x坐标(相对于屏幕)
496     pub dx: u32,
497     /// 矩形左上角的y坐标(相对于屏幕)
498     pub dy: u32,
499     /// 矩形的宽度
500     pub width: u32,
501     /// 矩形的高度
502     pub height: u32,
503     /// 用于填充矩形的颜色,是一个32位无符号整数
504     pub color: u32,
505     /// 光栅操作(Raster Operation),用于定义如何将颜色应用到矩形区域
506     pub rop: FillRectROP,
507 }
508 
509 impl FillRectData {
510     #[allow(dead_code)]
511     pub fn new(dx: u32, dy: u32, width: u32, height: u32, color: u32, rop: FillRectROP) -> Self {
512         Self {
513             dx,
514             dy,
515             width,
516             height,
517             color,
518             rop,
519         }
520     }
521 }
522 
523 /// 光栅操作(Raster Operation),用于定义如何将颜色应用到矩形区域
524 #[allow(dead_code)]
525 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
526 pub enum FillRectROP {
527     /// 复制操作,即直接将指定颜色应用到矩形区域,覆盖原有颜色。
528     Copy,
529     /// 异或操作,即将指定颜色与矩形区域原有颜色进行异或操作,结果颜色应用到矩形区域。
530     Xor,
531 }
532 
533 /// `CopyAreaData` 结构体用于表示一个矩形区域,并指定从哪个源位置复制数据。
534 ///
535 /// 注意,源位置必须是有意义的(即包围的矩形都必须得在屏幕内)
536 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
537 pub struct CopyAreaData {
538     /// 目标矩形左上角的x坐标
539     pub dx: i32,
540     /// 目标矩形左上角的y坐标
541     pub dy: i32,
542     /// 矩形的宽度
543     pub width: u32,
544     /// 矩形的高度
545     pub height: u32,
546     /// 源矩形左上角的x坐标
547     pub sx: i32,
548     /// 源矩形左上角的y坐标
549     pub sy: i32,
550 }
551 
552 impl CopyAreaData {
553     #[allow(dead_code)]
554     pub fn new(dx: i32, dy: i32, width: u32, height: u32, sx: i32, sy: i32) -> Self {
555         Self {
556             dx,
557             dy,
558             width,
559             height,
560             sx,
561             sy,
562         }
563     }
564 }
565 
566 /// `FbVarScreenInfo` 结构体用于描述屏幕的各种属性。
567 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
568 pub struct FbVarScreenInfo {
569     /// 可见分辨率的宽度
570     pub xres: u32,
571     /// 可见分辨率的高度
572     pub yres: u32,
573     /// 虚拟分辨率的宽度
574     pub xres_virtual: u32,
575     /// 虚拟分辨率的高度
576     pub yres_virtual: u32,
577     /// 从虚拟到可见分辨率的偏移量(宽度方向)
578     pub xoffset: u32,
579     /// 从虚拟到可见分辨率的偏移量(高度方向)
580     pub yoffset: u32,
581     /// 每像素的位数
582     pub bits_per_pixel: u32,
583     /// 颜色模式
584     pub color_mode: FbColorMode,
585     /// 红色位域
586     pub red: FbBitfield,
587     /// 绿色位域
588     pub green: FbBitfield,
589     /// 蓝色位域
590     pub blue: FbBitfield,
591     /// 透明度位域
592     pub transp: FbBitfield,
593     /// 像素格式
594     pub pixel_format: FbPixelFormat,
595     /// 激活标志(参见FB_ACTIVATE_*)
596     pub activate: FbActivateFlags,
597     /// 帧缓冲区的高度(像素) None表示未知
598     pub height: Option<u32>,
599     /// 帧缓冲区的宽度(像素) None表示未知
600     pub width: Option<u32>,
601     /// 像素时钟(皮秒)
602     pub pixclock: u32,
603     /// 左边距
604     pub left_margin: u32,
605     /// 右边距
606     pub right_margin: u32,
607     /// 上边距
608     pub upper_margin: u32,
609     /// 下边距
610     pub lower_margin: u32,
611     /// 水平同步的长度
612     pub hsync_len: u32,
613     /// 垂直同步的长度
614     pub vsync_len: u32,
615     /// 同步标志(参见FB_SYNC_*)
616     pub sync: FbSyncFlags,
617     /// 视频模式(参见FB_VMODE_*)
618     pub vmode: FbVModeFlags,
619     /// 逆时针旋转的角度
620     pub rotate_angle: u32,
621     /// 颜色空间
622     pub colorspace: V4l2Colorspace,
623 }
624 
625 impl Default for FbVarScreenInfo {
626     fn default() -> Self {
627         Self {
628             xres: Default::default(),
629             yres: Default::default(),
630             xres_virtual: Default::default(),
631             yres_virtual: Default::default(),
632             xoffset: Default::default(),
633             yoffset: Default::default(),
634             bits_per_pixel: Default::default(),
635             color_mode: Default::default(),
636             red: Default::default(),
637             green: Default::default(),
638             blue: Default::default(),
639             transp: Default::default(),
640             pixel_format: Default::default(),
641             activate: Default::default(),
642             height: None,
643             width: None,
644             pixclock: Default::default(),
645             left_margin: Default::default(),
646             right_margin: Default::default(),
647             upper_margin: Default::default(),
648             lower_margin: Default::default(),
649             hsync_len: Default::default(),
650             vsync_len: Default::default(),
651             sync: FbSyncFlags::empty(),
652             vmode: FbVModeFlags::empty(),
653             rotate_angle: Default::default(),
654             colorspace: Default::default(),
655         }
656     }
657 }
658 
659 /// 帧缓冲区的颜色模式
660 ///
661 /// 默认为彩色
662 #[allow(dead_code)]
663 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
664 pub enum FbColorMode {
665     /// 灰度
666     GrayScale,
667     /// 彩色
668     Color,
669     /// FOURCC
670     FourCC,
671 }
672 
673 impl Default for FbColorMode {
674     fn default() -> Self {
675         FbColorMode::Color
676     }
677 }
678 
679 /// `FbBitfield` 结构体用于描述颜色字段的位域。
680 ///
681 /// 所有的偏移量都是从右边开始,位于一个精确为'bits_per_pixel'宽度的"像素"值内。
682 /// 一个像素之后是一个位流,并且未经修改地写入视频内存。
683 ///
684 /// 对于伪颜色:所有颜色组件的偏移和长度应该相同。
685 /// 偏移指定了调色板索引在像素值中的最低有效位的位置。
686 /// 长度表示可用的调色板条目的数量(即条目数 = 1 << 长度)。
687 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
688 pub struct FbBitfield {
689     /// 位域的起始位置
690     pub offset: u32,
691     /// 位域的长度
692     pub length: u32,
693     /// 最高有效位是否在右边
694     pub msb_right: bool,
695 }
696 
697 impl FbBitfield {
698     #[allow(dead_code)]
699     pub fn new(offset: u32, length: u32, msb_right: bool) -> Self {
700         Self {
701             offset,
702             length,
703             msb_right,
704         }
705     }
706 }
707 
708 impl Default for FbBitfield {
709     fn default() -> Self {
710         Self {
711             offset: Default::default(),
712             length: Default::default(),
713             msb_right: Default::default(),
714         }
715     }
716 }
717 
718 bitflags! {
719     /// `FbActivateFlags` 用于描述帧缓冲区的激活标志。
720     ///
721     /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/include/uapi/linux/fb.h#198
722     pub struct FbActivateFlags: u32 {
723         /// 立即设置值(或vbl)
724         const FB_ACTIVATE_NOW = 0;
725         /// 在下一次打开时激活
726         const FB_ACTIVATE_NXTOPEN = 1;
727         /// don't set, round up impossible values
728         const FB_ACTIVATE_TEST = 2;
729         const FB_ACTIVATE_MASK = 15;
730 
731         /// 在下一个vbl上激活值
732         const FB_ACTIVATE_VBL = 16;
733         /// 在vbl上更改色彩映射
734         const FB_ACTIVATE_CHANGE_CMAP_VBL = 32;
735         /// 更改此fb上的所有VC
736         const FB_ACTIVATE_ALL = 64;
737         /// 即使没有变化也强制应用
738         const FB_ACTIVATE_FORCE = 128;
739         /// 使视频模式无效
740         const FB_ACTIVATE_INV_MODE = 256;
741         /// 用于KDSET vt ioctl
742         const FB_ACTIVATE_KD_TEXT = 512;
743     }
744 }
745 
746 impl Default for FbActivateFlags {
747     fn default() -> Self {
748         FbActivateFlags::FB_ACTIVATE_NOW
749     }
750 }
751 
752 #[allow(dead_code)]
753 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
754 pub enum FbPixelFormat {
755     Standard,
756     /// Hold And Modify
757     HAM,
758     /// order of pixels in each byte is reversed
759     Reserved,
760 }
761 
762 impl Default for FbPixelFormat {
763     fn default() -> Self {
764         FbPixelFormat::Standard
765     }
766 }
767 
768 bitflags! {
769     pub struct FbSyncFlags: u32 {
770         /// 水平同步高电平有效
771         const FB_SYNC_HOR_HIGH_ACT = 1;
772         /// 垂直同步高电平有效
773         const FB_SYNC_VERT_HIGH_ACT = 2;
774         /// 外部同步
775         const FB_SYNC_EXT = 4;
776         /// 复合同步高电平有效
777         const FB_SYNC_COMP_HIGH_ACT = 8;
778         /// 广播视频时序
779         const FB_SYNC_BROADCAST = 16;
780         /// sync on green
781         const FB_SYNC_ON_GREEN = 32;
782     }
783 }
784 
785 bitflags! {
786     /// `FbVModeFlags` 用于描述帧缓冲区的视频模式。
787     pub struct FbVModeFlags: u32 {
788         /// 非交错
789         const FB_VMODE_NONINTERLACED = 0;
790         /// 交错
791         const FB_VMODE_INTERLACED = 1;
792         /// 双扫描
793         const FB_VMODE_DOUBLE = 2;
794         /// 交错:首先是顶行
795         const FB_VMODE_ODD_FLD_FIRST = 4;
796         /// 掩码
797         const FB_VMODE_MASK = 255;
798         /// ywrap代替平移
799         const FB_VMODE_YWRAP = 256;
800         /// 平滑xpan可能(内部使用)
801         const FB_VMODE_SMOOTH_XPAN = 512;
802         /// 不更新x/yoffset
803         const FB_VMODE_CONUPDATE = 512;
804     }
805 }
806 
807 /// 视频颜色空间
808 #[allow(dead_code)]
809 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
810 pub enum V4l2Colorspace {
811     /// 默认颜色空间,即让驱动程序自行判断。只能用于视频捕获。
812     Default = 0,
813     /// SMPTE 170M:用于广播NTSC/PAL SDTV
814     Smpte170m = 1,
815     /// 过时的1998年前的SMPTE 240M HDTV标准,已被Rec 709取代
816     Smpte240m = 2,
817     /// Rec.709:用于HDTV
818     Rec709 = 3,
819     /// 已弃用,不要使用。没有驱动程序会返回这个。这是基于对bt878数据表的误解。
820     Bt878 = 4,
821     /// NTSC 1953颜色空间。只有在处理非常非常旧的NTSC录音时才有意义。已被SMPTE 170M取代。
822     System470M = 5,
823     /// EBU Tech 3213 PAL/SECAM颜色空间。
824     System470Bg = 6,
825     /// 实际上是V4L2_COLORSPACE_SRGB,V4L2_YCBCR_ENC_601和V4L2_QUANTIZATION_FULL_RANGE的简写。用于(Motion-)JPEG。
826     Jpeg = 7,
827     /// 用于RGB颜色空间,如大多数网络摄像头所产生的。
828     Srgb = 8,
829     /// opRGB颜色空间
830     Oprgb = 9,
831     /// BT.2020颜色空间,用于UHDTV。
832     Bt2020 = 10,
833     /// Raw颜色空间:用于RAW未处理的图像
834     Raw = 11,
835     /// DCI-P3颜色空间,用于电影投影机
836     DciP3 = 12,
837 
838     /// Largest supported colorspace value, assigned by the compiler, used
839     /// by the framework to check for invalid values.
840     Last,
841 }
842 
843 impl Default for V4l2Colorspace {
844     fn default() -> Self {
845         V4l2Colorspace::Default
846     }
847 }
848 
849 /// `FixedScreenInfo` 结构体用于描述屏幕的固定属性。
850 #[allow(dead_code)]
851 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
852 pub struct FixedScreenInfo {
853     // 字符串,用于标识屏幕,例如 "TT Builtin"
854     pub id: [char; 16],
855     // 帧缓冲区的起始物理地址
856     pub smem_start: Option<PhysAddr>,
857     // 帧缓冲区的长度
858     pub smem_len: usize,
859     // 屏幕类型,参考 FB_TYPE_
860     pub fb_type: FbType,
861     // 用于表示交错平面的小端辅助类型
862     pub type_aux: u32,
863     // 视觉类型,参考 FB_VISUAL_
864     pub visual: FbVisual,
865     // 水平缩放步长,如果无硬件缩放,则为0
866     pub xpanstep: u16,
867     // 垂直缩放步长,如果无硬件缩放,则为0
868     pub ypanstep: u16,
869     // 垂直环绕步长,如果无硬件环绕,则为0
870     pub ywrapstep: u16,
871     // 一行的大小(以字节为单位)
872     pub line_length: u32,
873     // 内存映射I/O端口的起始物理地址
874     pub mmio_start: Option<PhysAddr>,
875     // 内存映射I/O的长度
876     pub mmio_len: usize,
877     // 表示驱动器拥有的特定芯片/卡片类型
878     pub accel: FbAccel,
879     // 表示支持的特性,参考 FB_CAP_
880     pub capabilities: FbCapability,
881 }
882 
883 impl FixedScreenInfo {
884     /// 将字符串转换为长度为16的字符数组(包含结尾的`\0`)
885     ///
886     /// ## 参数
887     ///
888     /// - `name`: 字符串,长度不超过15,超过的部分将被截断
889     ///
890     /// ## 返回
891     ///
892     /// 长度为16的字符数组
893     pub const fn name2id(name: &str) -> [char; 16] {
894         let mut id = [0 as char; 16];
895         let mut i = 0;
896 
897         while i < 15 && i < name.len() {
898             id[i] = name.as_bytes()[i] as char;
899             i += 1;
900         }
901 
902         id[i] = '\0';
903         return id;
904     }
905 }
906 
907 impl Default for FixedScreenInfo {
908     fn default() -> Self {
909         Self {
910             id: Default::default(),
911             smem_start: None,
912             smem_len: Default::default(),
913             fb_type: FbType::PackedPixels,
914             type_aux: Default::default(),
915             visual: FbVisual::Mono10,
916             xpanstep: Default::default(),
917             ypanstep: Default::default(),
918             ywrapstep: Default::default(),
919             line_length: Default::default(),
920             mmio_start: None,
921             mmio_len: Default::default(),
922             accel: Default::default(),
923             capabilities: Default::default(),
924         }
925     }
926 }
927 
928 /// 帧缓冲类型
929 #[allow(dead_code)]
930 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
931 pub enum FbType {
932     /// 压缩像素
933     PackedPixels = 0,
934     /// 非交错平面
935     Planes = 1,
936     /// 交错平面
937     InterleavedPlanes = 2,
938     /// 文本/属性
939     Text = 3,
940     /// EGA/VGA平面
941     VgaPlanes = 4,
942     /// 由V4L2 FOURCC标识的类型
943     FourCC = 5,
944 }
945 
946 /// 帧缓冲视觉类型
947 #[allow(dead_code)]
948 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
949 pub enum FbVisual {
950     /// 单色。1=黑色 0=白色
951     Mono01 = 0,
952     /// 单色。1=白色 0=黑色
953     Mono10 = 1,
954     /// 真彩色
955     TrueColor = 2,
956     /// 伪彩色(如Atari)
957     PseudoColor = 3,
958     /// 直接颜色
959     DirectColor = 4,
960     /// 只读的伪彩色
961     StaticPseudoColor = 5,
962     /// 由FOURCC标识的类型
963     FourCC,
964 }
965 
966 #[allow(dead_code)]
967 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
968 pub enum FbCapability {
969     Default = 0,
970     /// 设备支持基于FOURCC的格式。
971     FourCC,
972 }
973 
974 impl Default for FbCapability {
975     fn default() -> Self {
976         FbCapability::Default
977     }
978 }
979 
980 /// 视频模式
981 #[allow(dead_code)]
982 #[derive(Debug, Clone, Eq, PartialEq)]
983 pub struct FbVideoMode {
984     /// 可选的名称
985     pub name: Option<String>,
986     /// 可选的刷新率
987     pub refresh: Option<u32>,
988     /// 水平分辨率
989     pub xres: u32,
990     /// 垂直分辨率
991     pub yres: u32,
992     /// 像素时钟
993     pub pixclock: u32,
994     /// 左边距
995     pub left_margin: u32,
996     /// 右边距
997     pub right_margin: u32,
998     /// 上边距
999     pub upper_margin: u32,
1000     /// 下边距
1001     pub lower_margin: u32,
1002     /// 水平同步长度
1003     pub hsync_len: u32,
1004     /// 垂直同步长度
1005     pub vsync_len: u32,
1006     /// 同步
1007     pub sync: FbSyncFlags,
1008     /// 视频模式
1009     pub vmode: FbVModeFlags,
1010     /// 标志
1011     pub flag: u32,
1012 }
1013 
1014 #[allow(dead_code)]
1015 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
1016 pub enum FbAccel {
1017     /// 没有硬件加速器
1018     None,
1019 
1020     AtariBlitter = 1,
1021     AmigaBlitter = 2,
1022     S3Trio64 = 3,
1023     NCR77C32BLT = 4,
1024     S3Virge = 5,
1025     AtiMach64GX = 6,
1026     DECTGA = 7,
1027     AtiMach64CT = 8,
1028     AtiMach64VT = 9,
1029     AtiMach64GT = 10,
1030     SunCreator = 11,
1031     SunCGSix = 12,
1032     SunLeo = 13,
1033     IMSTwinTurbo = 14,
1034     Acc3DLabsPermedia2 = 15,
1035     MatroxMGA2064W = 16,
1036     MatroxMGA1064SG = 17,
1037     MatroxMGA2164W = 18,
1038     MatroxMGA2164WAGP = 19,
1039     MatroxMGAG400 = 20,
1040     NV3 = 21,
1041     NV4 = 22,
1042     NV5 = 23,
1043     NV6 = 24,
1044     XGIVolariV = 25,
1045     XGIVolariZ = 26,
1046     Omap1610 = 27,
1047     TridentTGUI = 28,
1048     Trident3DImage = 29,
1049     TridentBlade3D = 30,
1050     TridentBladeXP = 31,
1051     CirrusAlpine = 32,
1052     NeoMagicNM2070 = 90,
1053     NeoMagicNM2090 = 91,
1054     NeoMagicNM2093 = 92,
1055     NeoMagicNM2097 = 93,
1056     NeoMagicNM2160 = 94,
1057     NeoMagicNM2200 = 95,
1058     NeoMagicNM2230 = 96,
1059     NeoMagicNM2360 = 97,
1060     NeoMagicNM2380 = 98,
1061     PXA3XX = 99,
1062 
1063     Savage4 = 0x80,
1064     Savage3D = 0x81,
1065     Savage3DMV = 0x82,
1066     Savage2000 = 0x83,
1067     SavageMXMV = 0x84,
1068     SavageMX = 0x85,
1069     SavageIXMV = 0x86,
1070     SavageIX = 0x87,
1071     ProSavagePM = 0x88,
1072     ProSavageKM = 0x89,
1073     S3Twister = 0x8a,
1074     S3TwisterK = 0x8b,
1075     SuperSavage = 0x8c,
1076     ProSavageDDR = 0x8d,
1077     ProSavageDDRK = 0x8e,
1078     // Add other accelerators here
1079 }
1080 
1081 impl Default for FbAccel {
1082     fn default() -> Self {
1083         FbAccel::None
1084     }
1085 }
1086 
1087 #[derive(Debug, Copy, Clone)]
1088 pub struct BootTimeScreenInfo {
1089     pub origin_x: u8,
1090     pub origin_y: u8,
1091     /// text mode时,每行的字符数
1092     pub origin_video_cols: u8,
1093     /// text mode时,行数
1094     pub origin_video_lines: u8,
1095     /// 标记屏幕是否为VGA类型
1096     pub is_vga: bool,
1097     /// video mode type
1098     pub video_type: BootTimeVideoType,
1099 
1100     // 以下字段用于线性帧缓冲区
1101     /// 线性帧缓冲区的起始物理地址
1102     pub lfb_base: PhysAddr,
1103     /// 线性帧缓冲区在初始化阶段被映射到的起始虚拟地址
1104     ///
1105     /// 这个值可能会被设置2次:
1106     ///
1107     /// - 内存管理初始化之前,early init阶段,临时映射
1108     /// - 内存管理初始化完毕,重新映射时被设置
1109     pub lfb_virt_base: Option<VirtAddr>,
1110     /// 线性帧缓冲区的长度
1111     pub lfb_size: usize,
1112     /// 线性帧缓冲区的宽度(像素)
1113     pub lfb_width: u32,
1114     /// 线性帧缓冲区的高度(像素)
1115     pub lfb_height: u32,
1116     /// 线性帧缓冲区的深度(位数)
1117     pub lfb_depth: u8,
1118     /// 红色位域的大小
1119     pub red_size: u8,
1120     /// 红色位域的偏移量(左移位数)
1121     pub red_pos: u8,
1122     /// 绿色位域的大小
1123     pub green_size: u8,
1124     /// 绿色位域的偏移量(左移位数)
1125     pub green_pos: u8,
1126     /// 蓝色位域的大小
1127     pub blue_size: u8,
1128     /// 蓝色位域的偏移量(左移位数)
1129     pub blue_pos: u8,
1130 }
1131 
1132 impl BootTimeScreenInfo {
1133     pub const DEFAULT: Self = Self {
1134         origin_x: 0,
1135         origin_y: 0,
1136         is_vga: false,
1137         lfb_base: PhysAddr::new(0),
1138         lfb_size: 0,
1139         lfb_width: 0,
1140         lfb_height: 0,
1141         red_size: 0,
1142         red_pos: 0,
1143         green_size: 0,
1144         green_pos: 0,
1145         blue_size: 0,
1146         blue_pos: 0,
1147         video_type: BootTimeVideoType::UnDefined,
1148         origin_video_cols: 0,
1149         origin_video_lines: 0,
1150         lfb_virt_base: None,
1151         lfb_depth: 0,
1152     };
1153 }
1154 
1155 /// Video types for different display hardware
1156 #[allow(dead_code)]
1157 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
1158 pub enum BootTimeVideoType {
1159     UnDefined,
1160     /// Monochrome Text Display
1161     Mda,
1162     /// CGA Display
1163     Cga,
1164     /// EGA/VGA in Monochrome Mode
1165     EgaM,
1166     /// EGA in Color Mode
1167     EgaC,
1168     /// VGA+ in Color Mode
1169     VgaC,
1170     /// VESA VGA in graphic mode
1171     Vlfb,
1172     /// ACER PICA-61 local S3 video
1173     PicaS3,
1174     /// MIPS Magnum 4000 G364 video
1175     MipsG364,
1176     /// Various SGI graphics hardware
1177     Sgi,
1178     /// DEC TGA
1179     TgaC,
1180     /// Sun frame buffer
1181     Sun,
1182     /// Sun PCI based frame buffer
1183     SunPci,
1184     /// PowerMacintosh frame buffer
1185     Pmac,
1186     /// EFI graphic mode
1187     Efi,
1188 }
1189 
1190 #[derive(Debug, Default)]
1191 pub struct FbCursor {
1192     /// 设置选项
1193     pub set_mode: FbCursorSetMode,
1194     /// 开关选项
1195     pub enable: bool,
1196     /// 表示光标图像的位操作,true表示XOR,false表示COPY
1197     pub rop: bool,
1198     /// 表示光标掩码(mask)的数据。掩码用于定义光标的形状,指定了哪些像素是光标的一部分。
1199     pub mask: Vec<u8>,
1200 
1201     /// 表示光标的热点位置,即在光标图像中被认为是"焦点"的位置
1202     pub hot_x: u32,
1203     pub hot_y: u32,
1204 
1205     /// 光标图像
1206     pub image: FbImage,
1207 }
1208 
1209 bitflags! {
1210     /// 硬件光标控制
1211     #[derive(Default)]
1212     pub struct FbCursorSetMode:u8 {
1213         /// 设置位图
1214         const FB_CUR_SETIMAGE = 0x01;
1215         /// 设置位置
1216         const FB_CUR_SETPOS   = 0x02;
1217         /// 设置热点
1218         const FB_CUR_SETHOT   = 0x04;
1219         /// ColorMap
1220         const FB_CUR_SETCMAP  = 0x08;
1221         /// 形状
1222         const FB_CUR_SETSHAPE = 0x10;
1223         /// Size
1224         const FB_CUR_SETSIZE  = 0x20;
1225         /// 全设置
1226         const FB_CUR_SETALL   = 0xFF;
1227     }
1228 }
1229 
1230 #[allow(dead_code)]
1231 #[derive(Debug, Clone, Copy)]
1232 pub enum ScrollMode {
1233     Move,
1234     PanMove,
1235     WrapMove,
1236     Redraw,
1237     PanRedraw,
1238 }
1239 
1240 impl Default for ScrollMode {
1241     /// ## 默认Move
1242     fn default() -> Self {
1243         Self::Move
1244     }
1245 }
1246 
1247 #[derive(Debug, Default, Clone)]
1248 pub struct FbImage {
1249     pub x: u32,
1250     pub y: u32,
1251     pub width: u32,
1252     pub height: u32,
1253     pub fg: u32,
1254     pub bg: u32,
1255     pub depth: u8,
1256     pub data: Vec<u8>,
1257 }
1258