xref: /DragonOS/kernel/src/driver/video/fbdev/base/mod.rs (revision c3dc6f2ff9169c309d1cbf47dcb9e4528d509b2f)
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) -> Result<(), SystemError> {
412         Err(SystemError::ENOSYS)
413     }
414 
415     /// 将帧缓冲区的内容映射到用户空间。
416     fn fb_mmap(&self, _vma: &Arc<LockedVMA>) -> Result<(), SystemError> {
417         Err(SystemError::ENOSYS)
418     }
419 
420     /// 卸载与该帧缓冲区相关的所有资源
421     fn fb_destroy(&self);
422 
423     /// 画光标
424     fn fb_cursor(&self, _cursor: &FbCursor) -> Result<(), SystemError> {
425         return Err(SystemError::ENOSYS);
426     }
427 
428     /// 画软光标(暂时简要实现)
429     fn soft_cursor(&self, cursor: FbCursor) -> Result<(), SystemError> {
430         let mut image = cursor.image.clone();
431         if cursor.enable {
432             match cursor.rop {
433                 true => {
434                     for i in 0..image.data.len() {
435                         image.data[i] ^= cursor.mask[i];
436                     }
437                 }
438                 false => {
439                     for i in 0..image.data.len() {
440                         image.data[i] &= cursor.mask[i];
441                     }
442                 }
443             }
444         }
445 
446         let _ = self.fb_image_blit(&image);
447 
448         Ok(())
449     }
450 
451     fn fb_sync(&self) -> Result<(), SystemError> {
452         return Err(SystemError::ENOSYS);
453     }
454 
455     /// 绘画位图
456     fn fb_image_blit(&self, image: &FbImage);
457 
458     fn fb_set_color_map(&self, _cmap: Vec<Color>) -> Result<(), SystemError> {
459         return Err(SystemError::ENOSYS);
460     }
461 }
462 
463 /// 帧缓冲区的状态
464 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
465 pub enum FbState {
466     Running = 0,
467     Suspended = 1,
468 }
469 
470 /// 屏幕黑屏模式。
471 #[allow(dead_code)]
472 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
473 pub enum BlankMode {
474     /// 取消屏幕黑屏, 垂直同步和水平同步均打开
475     Unblank,
476     /// 屏幕黑屏, 垂直同步和水平同步均打开
477     Normal,
478     /// 屏幕黑屏, 水平同步打开, 垂直同步关闭
479     HSync,
480     /// 屏幕黑屏, 水平同步关闭, 垂直同步打开
481     VSync,
482     /// 屏幕黑屏, 水平同步和垂直同步均关闭
483     Powerdown,
484 }
485 
486 /// `FillRectData` 结构体用于表示一个矩形区域并填充特定颜色。
487 ///
488 /// # 结构体字段
489 /// * `dx`:
490 /// * `dy`:
491 /// * `width`:
492 /// * `height`: 矩形的高度
493 /// * `color`: 用于填充矩形的颜色,是一个32位无符号整数
494 /// * `rop`: 光栅操作(Raster Operation),用于定义如何将颜色应用到矩形区域
495 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
496 pub struct FillRectData {
497     /// 矩形左上角的x坐标(相对于屏幕)
498     pub dx: u32,
499     /// 矩形左上角的y坐标(相对于屏幕)
500     pub dy: u32,
501     /// 矩形的宽度
502     pub width: u32,
503     /// 矩形的高度
504     pub height: u32,
505     /// 用于填充矩形的颜色,是一个32位无符号整数
506     pub color: u32,
507     /// 光栅操作(Raster Operation),用于定义如何将颜色应用到矩形区域
508     pub rop: FillRectROP,
509 }
510 
511 impl FillRectData {
512     #[allow(dead_code)]
513     pub fn new(dx: u32, dy: u32, width: u32, height: u32, color: u32, rop: FillRectROP) -> Self {
514         Self {
515             dx,
516             dy,
517             width,
518             height,
519             color,
520             rop,
521         }
522     }
523 }
524 
525 /// 光栅操作(Raster Operation),用于定义如何将颜色应用到矩形区域
526 #[allow(dead_code)]
527 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
528 pub enum FillRectROP {
529     /// 复制操作,即直接将指定颜色应用到矩形区域,覆盖原有颜色。
530     Copy,
531     /// 异或操作,即将指定颜色与矩形区域原有颜色进行异或操作,结果颜色应用到矩形区域。
532     Xor,
533 }
534 
535 /// `CopyAreaData` 结构体用于表示一个矩形区域,并指定从哪个源位置复制数据。
536 ///
537 /// 注意,源位置必须是有意义的(即包围的矩形都必须得在屏幕内)
538 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
539 pub struct CopyAreaData {
540     /// 目标矩形左上角的x坐标
541     pub dx: i32,
542     /// 目标矩形左上角的y坐标
543     pub dy: i32,
544     /// 矩形的宽度
545     pub width: u32,
546     /// 矩形的高度
547     pub height: u32,
548     /// 源矩形左上角的x坐标
549     pub sx: i32,
550     /// 源矩形左上角的y坐标
551     pub sy: i32,
552 }
553 
554 impl CopyAreaData {
555     #[allow(dead_code)]
556     pub fn new(dx: i32, dy: i32, width: u32, height: u32, sx: i32, sy: i32) -> Self {
557         Self {
558             dx,
559             dy,
560             width,
561             height,
562             sx,
563             sy,
564         }
565     }
566 }
567 
568 /// `FbVarScreenInfo` 结构体用于描述屏幕的各种属性。
569 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
570 pub struct FbVarScreenInfo {
571     /// 可见分辨率的宽度
572     pub xres: u32,
573     /// 可见分辨率的高度
574     pub yres: u32,
575     /// 虚拟分辨率的宽度
576     pub xres_virtual: u32,
577     /// 虚拟分辨率的高度
578     pub yres_virtual: u32,
579     /// 从虚拟到可见分辨率的偏移量(宽度方向)
580     pub xoffset: u32,
581     /// 从虚拟到可见分辨率的偏移量(高度方向)
582     pub yoffset: u32,
583     /// 每像素的位数
584     pub bits_per_pixel: u32,
585     /// 颜色模式
586     pub color_mode: FbColorMode,
587     /// 红色位域
588     pub red: FbBitfield,
589     /// 绿色位域
590     pub green: FbBitfield,
591     /// 蓝色位域
592     pub blue: FbBitfield,
593     /// 透明度位域
594     pub transp: FbBitfield,
595     /// 像素格式
596     pub pixel_format: FbPixelFormat,
597     /// 激活标志(参见FB_ACTIVATE_*)
598     pub activate: FbActivateFlags,
599     /// 帧缓冲区的高度(像素) None表示未知
600     pub height: Option<u32>,
601     /// 帧缓冲区的宽度(像素) None表示未知
602     pub width: Option<u32>,
603     /// 像素时钟(皮秒)
604     pub pixclock: u32,
605     /// 左边距
606     pub left_margin: u32,
607     /// 右边距
608     pub right_margin: u32,
609     /// 上边距
610     pub upper_margin: u32,
611     /// 下边距
612     pub lower_margin: u32,
613     /// 水平同步的长度
614     pub hsync_len: u32,
615     /// 垂直同步的长度
616     pub vsync_len: u32,
617     /// 同步标志(参见FB_SYNC_*)
618     pub sync: FbSyncFlags,
619     /// 视频模式(参见FB_VMODE_*)
620     pub vmode: FbVModeFlags,
621     /// 逆时针旋转的角度
622     pub rotate_angle: u32,
623     /// 颜色空间
624     pub colorspace: V4l2Colorspace,
625 }
626 
627 impl Default for FbVarScreenInfo {
628     fn default() -> Self {
629         Self {
630             xres: Default::default(),
631             yres: Default::default(),
632             xres_virtual: Default::default(),
633             yres_virtual: Default::default(),
634             xoffset: Default::default(),
635             yoffset: Default::default(),
636             bits_per_pixel: Default::default(),
637             color_mode: Default::default(),
638             red: Default::default(),
639             green: Default::default(),
640             blue: Default::default(),
641             transp: Default::default(),
642             pixel_format: Default::default(),
643             activate: Default::default(),
644             height: None,
645             width: None,
646             pixclock: Default::default(),
647             left_margin: Default::default(),
648             right_margin: Default::default(),
649             upper_margin: Default::default(),
650             lower_margin: Default::default(),
651             hsync_len: Default::default(),
652             vsync_len: Default::default(),
653             sync: FbSyncFlags::empty(),
654             vmode: FbVModeFlags::empty(),
655             rotate_angle: Default::default(),
656             colorspace: Default::default(),
657         }
658     }
659 }
660 
661 /// 帧缓冲区的颜色模式
662 ///
663 /// 默认为彩色
664 #[allow(dead_code)]
665 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
666 pub enum FbColorMode {
667     /// 灰度
668     GrayScale,
669     /// 彩色
670     Color,
671     /// FOURCC
672     FourCC,
673 }
674 
675 impl Default for FbColorMode {
676     fn default() -> Self {
677         FbColorMode::Color
678     }
679 }
680 
681 /// `FbBitfield` 结构体用于描述颜色字段的位域。
682 ///
683 /// 所有的偏移量都是从右边开始,位于一个精确为'bits_per_pixel'宽度的"像素"值内。
684 /// 一个像素之后是一个位流,并且未经修改地写入视频内存。
685 ///
686 /// 对于伪颜色:所有颜色组件的偏移和长度应该相同。
687 /// 偏移指定了调色板索引在像素值中的最低有效位的位置。
688 /// 长度表示可用的调色板条目的数量(即条目数 = 1 << 长度)。
689 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
690 pub struct FbBitfield {
691     /// 位域的起始位置
692     pub offset: u32,
693     /// 位域的长度
694     pub length: u32,
695     /// 最高有效位是否在右边
696     pub msb_right: bool,
697 }
698 
699 impl FbBitfield {
700     #[allow(dead_code)]
701     pub fn new(offset: u32, length: u32, msb_right: bool) -> Self {
702         Self {
703             offset,
704             length,
705             msb_right,
706         }
707     }
708 }
709 
710 impl Default for FbBitfield {
711     fn default() -> Self {
712         Self {
713             offset: Default::default(),
714             length: Default::default(),
715             msb_right: Default::default(),
716         }
717     }
718 }
719 
720 bitflags! {
721     /// `FbActivateFlags` 用于描述帧缓冲区的激活标志。
722     ///
723     /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/include/uapi/linux/fb.h#198
724     pub struct FbActivateFlags: u32 {
725         /// 立即设置值(或vbl)
726         const FB_ACTIVATE_NOW = 0;
727         /// 在下一次打开时激活
728         const FB_ACTIVATE_NXTOPEN = 1;
729         /// don't set, round up impossible values
730         const FB_ACTIVATE_TEST = 2;
731         const FB_ACTIVATE_MASK = 15;
732 
733         /// 在下一个vbl上激活值
734         const FB_ACTIVATE_VBL = 16;
735         /// 在vbl上更改色彩映射
736         const FB_ACTIVATE_CHANGE_CMAP_VBL = 32;
737         /// 更改此fb上的所有VC
738         const FB_ACTIVATE_ALL = 64;
739         /// 即使没有变化也强制应用
740         const FB_ACTIVATE_FORCE = 128;
741         /// 使视频模式无效
742         const FB_ACTIVATE_INV_MODE = 256;
743         /// 用于KDSET vt ioctl
744         const FB_ACTIVATE_KD_TEXT = 512;
745     }
746 }
747 
748 impl Default for FbActivateFlags {
749     fn default() -> Self {
750         FbActivateFlags::FB_ACTIVATE_NOW
751     }
752 }
753 
754 #[allow(dead_code)]
755 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
756 pub enum FbPixelFormat {
757     Standard,
758     /// Hold And Modify
759     HAM,
760     /// order of pixels in each byte is reversed
761     Reserved,
762 }
763 
764 impl Default for FbPixelFormat {
765     fn default() -> Self {
766         FbPixelFormat::Standard
767     }
768 }
769 
770 bitflags! {
771     pub struct FbSyncFlags: u32 {
772         /// 水平同步高电平有效
773         const FB_SYNC_HOR_HIGH_ACT = 1;
774         /// 垂直同步高电平有效
775         const FB_SYNC_VERT_HIGH_ACT = 2;
776         /// 外部同步
777         const FB_SYNC_EXT = 4;
778         /// 复合同步高电平有效
779         const FB_SYNC_COMP_HIGH_ACT = 8;
780         /// 广播视频时序
781         const FB_SYNC_BROADCAST = 16;
782         /// sync on green
783         const FB_SYNC_ON_GREEN = 32;
784     }
785 }
786 
787 bitflags! {
788     /// `FbVModeFlags` 用于描述帧缓冲区的视频模式。
789     pub struct FbVModeFlags: u32 {
790         /// 非交错
791         const FB_VMODE_NONINTERLACED = 0;
792         /// 交错
793         const FB_VMODE_INTERLACED = 1;
794         /// 双扫描
795         const FB_VMODE_DOUBLE = 2;
796         /// 交错:首先是顶行
797         const FB_VMODE_ODD_FLD_FIRST = 4;
798         /// 掩码
799         const FB_VMODE_MASK = 255;
800         /// ywrap代替平移
801         const FB_VMODE_YWRAP = 256;
802         /// 平滑xpan可能(内部使用)
803         const FB_VMODE_SMOOTH_XPAN = 512;
804         /// 不更新x/yoffset
805         const FB_VMODE_CONUPDATE = 512;
806     }
807 }
808 
809 /// 视频颜色空间
810 #[allow(dead_code)]
811 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
812 pub enum V4l2Colorspace {
813     /// 默认颜色空间,即让驱动程序自行判断。只能用于视频捕获。
814     Default = 0,
815     /// SMPTE 170M:用于广播NTSC/PAL SDTV
816     Smpte170m = 1,
817     /// 过时的1998年前的SMPTE 240M HDTV标准,已被Rec 709取代
818     Smpte240m = 2,
819     /// Rec.709:用于HDTV
820     Rec709 = 3,
821     /// 已弃用,不要使用。没有驱动程序会返回这个。这是基于对bt878数据表的误解。
822     Bt878 = 4,
823     /// NTSC 1953颜色空间。只有在处理非常非常旧的NTSC录音时才有意义。已被SMPTE 170M取代。
824     System470M = 5,
825     /// EBU Tech 3213 PAL/SECAM颜色空间。
826     System470Bg = 6,
827     /// 实际上是V4L2_COLORSPACE_SRGB,V4L2_YCBCR_ENC_601和V4L2_QUANTIZATION_FULL_RANGE的简写。用于(Motion-)JPEG。
828     Jpeg = 7,
829     /// 用于RGB颜色空间,如大多数网络摄像头所产生的。
830     Srgb = 8,
831     /// opRGB颜色空间
832     Oprgb = 9,
833     /// BT.2020颜色空间,用于UHDTV。
834     Bt2020 = 10,
835     /// Raw颜色空间:用于RAW未处理的图像
836     Raw = 11,
837     /// DCI-P3颜色空间,用于电影投影机
838     DciP3 = 12,
839 
840     /// Largest supported colorspace value, assigned by the compiler, used
841     /// by the framework to check for invalid values.
842     Last,
843 }
844 
845 impl Default for V4l2Colorspace {
846     fn default() -> Self {
847         V4l2Colorspace::Default
848     }
849 }
850 
851 /// `FixedScreenInfo` 结构体用于描述屏幕的固定属性。
852 #[allow(dead_code)]
853 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
854 pub struct FixedScreenInfo {
855     // 字符串,用于标识屏幕,例如 "TT Builtin"
856     pub id: [char; 16],
857     // 帧缓冲区的起始物理地址
858     pub smem_start: Option<PhysAddr>,
859     // 帧缓冲区的长度
860     pub smem_len: usize,
861     // 屏幕类型,参考 FB_TYPE_
862     pub fb_type: FbType,
863     // 用于表示交错平面的小端辅助类型
864     pub type_aux: u32,
865     // 视觉类型,参考 FB_VISUAL_
866     pub visual: FbVisual,
867     // 水平缩放步长,如果无硬件缩放,则为0
868     pub xpanstep: u16,
869     // 垂直缩放步长,如果无硬件缩放,则为0
870     pub ypanstep: u16,
871     // 垂直环绕步长,如果无硬件环绕,则为0
872     pub ywrapstep: u16,
873     // 一行的大小(以字节为单位)
874     pub line_length: u32,
875     // 内存映射I/O端口的起始物理地址
876     pub mmio_start: Option<PhysAddr>,
877     // 内存映射I/O的长度
878     pub mmio_len: usize,
879     // 表示驱动器拥有的特定芯片/卡片类型
880     pub accel: FbAccel,
881     // 表示支持的特性,参考 FB_CAP_
882     pub capabilities: FbCapability,
883 }
884 
885 impl FixedScreenInfo {
886     /// 将字符串转换为长度为16的字符数组(包含结尾的`\0`)
887     ///
888     /// ## 参数
889     ///
890     /// - `name`: 字符串,长度不超过15,超过的部分将被截断
891     ///
892     /// ## 返回
893     ///
894     /// 长度为16的字符数组
895     pub const fn name2id(name: &str) -> [char; 16] {
896         let mut id = [0 as char; 16];
897         let mut i = 0;
898 
899         while i < 15 && i < name.len() {
900             id[i] = name.as_bytes()[i] as char;
901             i += 1;
902         }
903 
904         id[i] = '\0';
905         return id;
906     }
907 }
908 
909 impl Default for FixedScreenInfo {
910     fn default() -> Self {
911         Self {
912             id: Default::default(),
913             smem_start: None,
914             smem_len: Default::default(),
915             fb_type: FbType::PackedPixels,
916             type_aux: Default::default(),
917             visual: FbVisual::Mono10,
918             xpanstep: Default::default(),
919             ypanstep: Default::default(),
920             ywrapstep: Default::default(),
921             line_length: Default::default(),
922             mmio_start: None,
923             mmio_len: Default::default(),
924             accel: Default::default(),
925             capabilities: Default::default(),
926         }
927     }
928 }
929 
930 /// 帧缓冲类型
931 #[allow(dead_code)]
932 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
933 pub enum FbType {
934     /// 压缩像素
935     PackedPixels = 0,
936     /// 非交错平面
937     Planes = 1,
938     /// 交错平面
939     InterleavedPlanes = 2,
940     /// 文本/属性
941     Text = 3,
942     /// EGA/VGA平面
943     VgaPlanes = 4,
944     /// 由V4L2 FOURCC标识的类型
945     FourCC = 5,
946 }
947 
948 /// 帧缓冲视觉类型
949 #[allow(dead_code)]
950 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
951 pub enum FbVisual {
952     /// 单色。1=黑色 0=白色
953     Mono01 = 0,
954     /// 单色。1=白色 0=黑色
955     Mono10 = 1,
956     /// 真彩色
957     TrueColor = 2,
958     /// 伪彩色(如Atari)
959     PseudoColor = 3,
960     /// 直接颜色
961     DirectColor = 4,
962     /// 只读的伪彩色
963     StaticPseudoColor = 5,
964     /// 由FOURCC标识的类型
965     FourCC,
966 }
967 
968 #[allow(dead_code)]
969 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
970 pub enum FbCapability {
971     Default = 0,
972     /// 设备支持基于FOURCC的格式。
973     FourCC,
974 }
975 
976 impl Default for FbCapability {
977     fn default() -> Self {
978         FbCapability::Default
979     }
980 }
981 
982 /// 视频模式
983 #[allow(dead_code)]
984 #[derive(Debug, Clone, Eq, PartialEq)]
985 pub struct FbVideoMode {
986     /// 可选的名称
987     pub name: Option<String>,
988     /// 可选的刷新率
989     pub refresh: Option<u32>,
990     /// 水平分辨率
991     pub xres: u32,
992     /// 垂直分辨率
993     pub yres: u32,
994     /// 像素时钟
995     pub pixclock: u32,
996     /// 左边距
997     pub left_margin: u32,
998     /// 右边距
999     pub right_margin: u32,
1000     /// 上边距
1001     pub upper_margin: u32,
1002     /// 下边距
1003     pub lower_margin: u32,
1004     /// 水平同步长度
1005     pub hsync_len: u32,
1006     /// 垂直同步长度
1007     pub vsync_len: u32,
1008     /// 同步
1009     pub sync: FbSyncFlags,
1010     /// 视频模式
1011     pub vmode: FbVModeFlags,
1012     /// 标志
1013     pub flag: u32,
1014 }
1015 
1016 #[allow(dead_code)]
1017 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
1018 pub enum FbAccel {
1019     /// 没有硬件加速器
1020     None,
1021 
1022     AtariBlitter = 1,
1023     AmigaBlitter = 2,
1024     S3Trio64 = 3,
1025     NCR77C32BLT = 4,
1026     S3Virge = 5,
1027     AtiMach64GX = 6,
1028     DECTGA = 7,
1029     AtiMach64CT = 8,
1030     AtiMach64VT = 9,
1031     AtiMach64GT = 10,
1032     SunCreator = 11,
1033     SunCGSix = 12,
1034     SunLeo = 13,
1035     IMSTwinTurbo = 14,
1036     Acc3DLabsPermedia2 = 15,
1037     MatroxMGA2064W = 16,
1038     MatroxMGA1064SG = 17,
1039     MatroxMGA2164W = 18,
1040     MatroxMGA2164WAGP = 19,
1041     MatroxMGAG400 = 20,
1042     NV3 = 21,
1043     NV4 = 22,
1044     NV5 = 23,
1045     NV6 = 24,
1046     XGIVolariV = 25,
1047     XGIVolariZ = 26,
1048     Omap1610 = 27,
1049     TridentTGUI = 28,
1050     Trident3DImage = 29,
1051     TridentBlade3D = 30,
1052     TridentBladeXP = 31,
1053     CirrusAlpine = 32,
1054     NeoMagicNM2070 = 90,
1055     NeoMagicNM2090 = 91,
1056     NeoMagicNM2093 = 92,
1057     NeoMagicNM2097 = 93,
1058     NeoMagicNM2160 = 94,
1059     NeoMagicNM2200 = 95,
1060     NeoMagicNM2230 = 96,
1061     NeoMagicNM2360 = 97,
1062     NeoMagicNM2380 = 98,
1063     PXA3XX = 99,
1064 
1065     Savage4 = 0x80,
1066     Savage3D = 0x81,
1067     Savage3DMV = 0x82,
1068     Savage2000 = 0x83,
1069     SavageMXMV = 0x84,
1070     SavageMX = 0x85,
1071     SavageIXMV = 0x86,
1072     SavageIX = 0x87,
1073     ProSavagePM = 0x88,
1074     ProSavageKM = 0x89,
1075     S3Twister = 0x8a,
1076     S3TwisterK = 0x8b,
1077     SuperSavage = 0x8c,
1078     ProSavageDDR = 0x8d,
1079     ProSavageDDRK = 0x8e,
1080     // Add other accelerators here
1081 }
1082 
1083 impl Default for FbAccel {
1084     fn default() -> Self {
1085         FbAccel::None
1086     }
1087 }
1088 
1089 #[derive(Debug, Copy, Clone)]
1090 pub struct BootTimeScreenInfo {
1091     pub origin_x: u8,
1092     pub origin_y: u8,
1093     /// text mode时,每行的字符数
1094     pub origin_video_cols: u8,
1095     /// text mode时,行数
1096     pub origin_video_lines: u8,
1097     /// 标记屏幕是否为VGA类型
1098     pub is_vga: bool,
1099     /// video mode type
1100     pub video_type: BootTimeVideoType,
1101 
1102     // 以下字段用于线性帧缓冲区
1103     /// 线性帧缓冲区的起始物理地址
1104     pub lfb_base: PhysAddr,
1105     /// 线性帧缓冲区在初始化阶段被映射到的起始虚拟地址
1106     ///
1107     /// 这个值可能会被设置2次:
1108     ///
1109     /// - 内存管理初始化之前,early init阶段,临时映射
1110     /// - 内存管理初始化完毕,重新映射时被设置
1111     pub lfb_virt_base: Option<VirtAddr>,
1112     /// 线性帧缓冲区的长度
1113     pub lfb_size: usize,
1114     /// 线性帧缓冲区的宽度(像素)
1115     pub lfb_width: u32,
1116     /// 线性帧缓冲区的高度(像素)
1117     pub lfb_height: u32,
1118     /// 线性帧缓冲区的深度(位数)
1119     pub lfb_depth: u8,
1120     /// 红色位域的大小
1121     pub red_size: u8,
1122     /// 红色位域的偏移量(左移位数)
1123     pub red_pos: u8,
1124     /// 绿色位域的大小
1125     pub green_size: u8,
1126     /// 绿色位域的偏移量(左移位数)
1127     pub green_pos: u8,
1128     /// 蓝色位域的大小
1129     pub blue_size: u8,
1130     /// 蓝色位域的偏移量(左移位数)
1131     pub blue_pos: u8,
1132 }
1133 
1134 impl BootTimeScreenInfo {
1135     pub const DEFAULT: Self = Self {
1136         origin_x: 0,
1137         origin_y: 0,
1138         is_vga: false,
1139         lfb_base: PhysAddr::new(0),
1140         lfb_size: 0,
1141         lfb_width: 0,
1142         lfb_height: 0,
1143         red_size: 0,
1144         red_pos: 0,
1145         green_size: 0,
1146         green_pos: 0,
1147         blue_size: 0,
1148         blue_pos: 0,
1149         video_type: BootTimeVideoType::UnDefined,
1150         origin_video_cols: 0,
1151         origin_video_lines: 0,
1152         lfb_virt_base: None,
1153         lfb_depth: 0,
1154     };
1155 }
1156 
1157 /// Video types for different display hardware
1158 #[allow(dead_code)]
1159 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
1160 pub enum BootTimeVideoType {
1161     UnDefined,
1162     /// Monochrome Text Display
1163     Mda,
1164     /// CGA Display
1165     Cga,
1166     /// EGA/VGA in Monochrome Mode
1167     EgaM,
1168     /// EGA in Color Mode
1169     EgaC,
1170     /// VGA+ in Color Mode
1171     VgaC,
1172     /// VESA VGA in graphic mode
1173     Vlfb,
1174     /// ACER PICA-61 local S3 video
1175     PicaS3,
1176     /// MIPS Magnum 4000 G364 video
1177     MipsG364,
1178     /// Various SGI graphics hardware
1179     Sgi,
1180     /// DEC TGA
1181     TgaC,
1182     /// Sun frame buffer
1183     Sun,
1184     /// Sun PCI based frame buffer
1185     SunPci,
1186     /// PowerMacintosh frame buffer
1187     Pmac,
1188     /// EFI graphic mode
1189     Efi,
1190 }
1191 
1192 #[derive(Debug, Default)]
1193 pub struct FbCursor {
1194     /// 设置选项
1195     pub set_mode: FbCursorSetMode,
1196     /// 开关选项
1197     pub enable: bool,
1198     /// 表示光标图像的位操作,true表示XOR,false表示COPY
1199     pub rop: bool,
1200     /// 表示光标掩码(mask)的数据。掩码用于定义光标的形状,指定了哪些像素是光标的一部分。
1201     pub mask: Vec<u8>,
1202 
1203     /// 表示光标的热点位置,即在光标图像中被认为是"焦点"的位置
1204     pub hot_x: u32,
1205     pub hot_y: u32,
1206 
1207     /// 光标图像
1208     pub image: FbImage,
1209 }
1210 
1211 bitflags! {
1212     /// 硬件光标控制
1213     #[derive(Default)]
1214     pub struct FbCursorSetMode:u8 {
1215         /// 设置位图
1216         const FB_CUR_SETIMAGE = 0x01;
1217         /// 设置位置
1218         const FB_CUR_SETPOS   = 0x02;
1219         /// 设置热点
1220         const FB_CUR_SETHOT   = 0x04;
1221         /// ColorMap
1222         const FB_CUR_SETCMAP  = 0x08;
1223         /// 形状
1224         const FB_CUR_SETSHAPE = 0x10;
1225         /// Size
1226         const FB_CUR_SETSIZE  = 0x20;
1227         /// 全设置
1228         const FB_CUR_SETALL   = 0xFF;
1229     }
1230 }
1231 
1232 #[allow(dead_code)]
1233 #[derive(Debug, Clone, Copy)]
1234 pub enum ScrollMode {
1235     Move,
1236     PanMove,
1237     WrapMove,
1238     Redraw,
1239     PanRedraw,
1240 }
1241 
1242 impl Default for ScrollMode {
1243     /// ## 默认Move
1244     fn default() -> Self {
1245         Self::Move
1246     }
1247 }
1248 
1249 #[derive(Debug, Default, Clone)]
1250 pub struct FbImage {
1251     pub x: u32,
1252     pub y: u32,
1253     pub width: u32,
1254     pub height: u32,
1255     pub fg: u32,
1256     pub bg: u32,
1257     pub depth: u8,
1258     pub data: Vec<u8>,
1259 }
1260