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