xref: /DragonOS/kernel/src/driver/video/fbdev/base/mod.rs (revision 08a2ee408498b0db4c76c57b149f1cf047758f3c)
1 use alloc::{string::String, sync::Arc};
2 
3 use crate::{
4     driver::base::device::Device,
5     mm::{ucontext::LockedVMA, PhysAddr},
6     syscall::SystemError,
7 };
8 
9 pub mod fbcon;
10 pub mod fbmem;
11 
12 /// 帧缓冲区应该实现的接口
13 pub trait FrameBuffer: FrameBufferInfo + FrameBufferOps + Device {}
14 
15 /// 帧缓冲区信息
16 pub trait FrameBufferInfo {
17     /// Amount of ioremapped VRAM or 0
18     fn screen_size(&self) -> usize;
19 
20     /// 获取当前的可变帧缓冲信息
21     fn current_fb_var(&self) -> &FbVarScreenInfo;
22 
23     /// 获取当前的可变帧缓冲信息(可变引用)
24     fn current_fb_var_mut(&mut self) -> &mut FbVarScreenInfo;
25 
26     /// 获取当前的固定帧缓冲信息
27     fn current_fb_fix(&self) -> &FixedScreenInfo;
28 
29     /// 获取当前的固定帧缓冲信息(可变引用)
30     fn current_fb_fix_mut(&mut self) -> &mut FixedScreenInfo;
31 
32     /// 获取当前的视频模式
33     fn video_mode(&self) -> Option<&FbVideoMode>;
34 }
35 
36 /// 帧缓冲区操作
37 ///
38 /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/fb.h#237
39 pub trait FrameBufferOps {
40     fn fb_open(&self, user: bool);
41     fn fb_release(&self, user: bool);
42 
43     /// 读取帧缓冲区的内容。
44     ///
45     /// 对于具有奇特非线性布局的帧缓冲区或正常内存映射访问无法工作的帧缓冲区,可以使用此方法。
46     fn fb_read(&self, _buf: &mut [u8], _pos: usize) -> Result<usize, SystemError> {
47         Err(SystemError::ENOSYS)
48     }
49 
50     /// 将帧缓冲区的内容写入。
51     ///
52     /// 对于具有奇特非线性布局的帧缓冲区或正常内存映射访问无法工作的帧缓冲区,可以使用此方法。
53     fn fb_write(&self, _buf: &[u8], _pos: usize) -> Result<usize, SystemError> {
54         Err(SystemError::ENOSYS)
55     }
56 
57     /// 设置帧缓冲区的颜色寄存器。
58     ///
59     /// 颜色寄存器的数量和含义取决于帧缓冲区的硬件。
60     ///
61     /// ## 参数
62     ///
63     /// - `regno`:寄存器编号。
64     /// - `red`:红色分量。
65     /// - `green`:绿色分量。
66     /// - `blue`:蓝色分量。
67     fn fb_set_color_register(
68         &self,
69         regno: u16,
70         red: u16,
71         green: u16,
72         blue: u16,
73     ) -> Result<(), SystemError>;
74 
75     /// 设置帧缓冲区的黑屏模式
76     fn fb_blank(&self, blank_mode: BlankMode) -> Result<(), SystemError>;
77 
78     /// 在帧缓冲区中绘制一个矩形。
79     fn fb_fillrect(&self, _data: FillRectData) -> Result<(), SystemError> {
80         Err(SystemError::ENOSYS)
81     }
82 
83     /// 将数据从一处复制到另一处。
84     fn fb_copyarea(&self, _data: CopyAreaData) -> Result<(), SystemError> {
85         Err(SystemError::ENOSYS)
86     }
87 
88     /// 将帧缓冲区的内容映射到用户空间。
89     fn fb_mmap(&self, _vma: &Arc<LockedVMA>) -> Result<(), SystemError> {
90         Err(SystemError::ENOSYS)
91     }
92 
93     /// 卸载与该帧缓冲区相关的所有资源
94     fn fb_destroy(&self);
95 }
96 
97 /// 屏幕黑屏模式。
98 #[allow(dead_code)]
99 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
100 pub enum BlankMode {
101     /// 取消屏幕黑屏, 垂直同步和水平同步均打开
102     Unblank,
103     /// 屏幕黑屏, 垂直同步和水平同步均打开
104     Normal,
105     /// 屏幕黑屏, 水平同步打开, 垂直同步关闭
106     HSync,
107     /// 屏幕黑屏, 水平同步关闭, 垂直同步打开
108     VSync,
109     /// 屏幕黑屏, 水平同步和垂直同步均关闭
110     Powerdown,
111 }
112 
113 /// `FillRectData` 结构体用于表示一个矩形区域并填充特定颜色。
114 ///
115 /// # 结构体字段
116 /// * `dx`:
117 /// * `dy`:
118 /// * `width`:
119 /// * `height`: 矩形的高度
120 /// * `color`: 用于填充矩形的颜色,是一个32位无符号整数
121 /// * `rop`: 光栅操作(Raster Operation),用于定义如何将颜色应用到矩形区域
122 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
123 pub struct FillRectData {
124     /// 矩形左上角的x坐标(相对于屏幕)
125     pub dx: u32,
126     /// 矩形左上角的y坐标(相对于屏幕)
127     pub dy: u32,
128     /// 矩形的宽度
129     pub width: u32,
130     /// 矩形的高度
131     pub height: u32,
132     /// 用于填充矩形的颜色,是一个32位无符号整数
133     pub color: u32,
134     /// 光栅操作(Raster Operation),用于定义如何将颜色应用到矩形区域
135     pub rop: FillRectROP,
136 }
137 
138 impl FillRectData {
139     #[allow(dead_code)]
140     pub fn new(dx: u32, dy: u32, width: u32, height: u32, color: u32, rop: FillRectROP) -> Self {
141         Self {
142             dx,
143             dy,
144             width,
145             height,
146             color,
147             rop,
148         }
149     }
150 }
151 
152 /// 光栅操作(Raster Operation),用于定义如何将颜色应用到矩形区域
153 #[allow(dead_code)]
154 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
155 pub enum FillRectROP {
156     /// 复制操作,即直接将指定颜色应用到矩形区域,覆盖原有颜色。
157     Copy,
158     /// 异或操作,即将指定颜色与矩形区域原有颜色进行异或操作,结果颜色应用到矩形区域。
159     Xor,
160 }
161 
162 /// `CopyAreaData` 结构体用于表示一个矩形区域,并指定从哪个源位置复制数据。
163 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
164 pub struct CopyAreaData {
165     /// 目标矩形左上角的x坐标
166     pub dx: u32,
167     /// 目标矩形左上角的y坐标
168     pub dy: u32,
169     /// 矩形的宽度
170     pub width: u32,
171     /// 矩形的高度
172     pub height: u32,
173     /// 源矩形左上角的x坐标
174     pub sx: u32,
175     /// 源矩形左上角的y坐标
176     pub sy: u32,
177 }
178 
179 impl CopyAreaData {
180     #[allow(dead_code)]
181     pub fn new(dx: u32, dy: u32, width: u32, height: u32, sx: u32, sy: u32) -> Self {
182         Self {
183             dx,
184             dy,
185             width,
186             height,
187             sx,
188             sy,
189         }
190     }
191 }
192 
193 /// `FbVarScreenInfo` 结构体用于描述屏幕的各种属性。
194 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
195 pub struct FbVarScreenInfo {
196     /// 可见分辨率的宽度
197     pub xres: u32,
198     /// 可见分辨率的高度
199     pub yres: u32,
200     /// 虚拟分辨率的宽度
201     pub xres_virtual: u32,
202     /// 虚拟分辨率的高度
203     pub yres_virtual: u32,
204     /// 从虚拟到可见分辨率的偏移量(宽度方向)
205     pub xoffset: u32,
206     /// 从虚拟到可见分辨率的偏移量(高度方向)
207     pub yoffset: u32,
208     /// 每像素的位数
209     pub bits_per_pixel: u32,
210     /// 颜色模式
211     pub color_mode: FbColorMode,
212     /// 红色位域
213     pub red: FbBitfield,
214     /// 绿色位域
215     pub green: FbBitfield,
216     /// 蓝色位域
217     pub blue: FbBitfield,
218     /// 透明度位域
219     pub transp: FbBitfield,
220     /// 像素格式
221     pub pixel_format: FbPixelFormat,
222     /// 激活标志(参见FB_ACTIVATE_*)
223     pub activate: FbActivateFlags,
224     /// 帧缓冲区的高度(像素)
225     pub height: u32,
226     /// 帧缓冲区的宽度(像素)
227     pub width: u32,
228     /// 像素时钟(皮秒)
229     pub pixclock: u32,
230     /// 左边距
231     pub left_margin: u32,
232     /// 右边距
233     pub right_margin: u32,
234     /// 上边距
235     pub upper_margin: u32,
236     /// 下边距
237     pub lower_margin: u32,
238     /// 水平同步的长度
239     pub hsync_len: u32,
240     /// 垂直同步的长度
241     pub vsync_len: u32,
242     /// 同步标志(参见FB_SYNC_*)
243     pub sync: FbSyncFlags,
244     /// 视频模式(参见FB_VMODE_*)
245     pub vmode: FbVModeFlags,
246     /// 逆时针旋转的角度
247     pub rotate_angle: u32,
248     /// 颜色空间
249     pub colorspace: V4l2Colorspace,
250 }
251 
252 #[allow(dead_code)]
253 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
254 pub enum FbColorMode {
255     /// 灰度
256     GrayScale,
257     /// 彩色
258     Color,
259     /// FOURCC
260     FourCC,
261 }
262 
263 /// `FbBitfield` 结构体用于描述颜色字段的位域。
264 ///
265 /// 所有的偏移量都是从右边开始,位于一个精确为'bits_per_pixel'宽度的"像素"值内。
266 /// 一个像素之后是一个位流,并且未经修改地写入视频内存。
267 ///
268 /// 对于伪颜色:所有颜色组件的偏移和长度应该相同。
269 /// 偏移指定了调色板索引在像素值中的最低有效位的位置。
270 /// 长度表示可用的调色板条目的数量(即条目数 = 1 << 长度)。
271 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
272 pub struct FbBitfield {
273     /// 位域的起始位置
274     pub offset: u32,
275     /// 位域的长度
276     pub length: u32,
277     /// 最高有效位是否在右边
278     pub msb_right: bool,
279 }
280 
281 impl FbBitfield {
282     #[allow(dead_code)]
283     pub fn new(offset: u32, length: u32, msb_right: bool) -> Self {
284         Self {
285             offset,
286             length,
287             msb_right,
288         }
289     }
290 }
291 
292 bitflags! {
293     /// `FbActivateFlags` 用于描述帧缓冲区的激活标志。
294     ///
295     /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/include/uapi/linux/fb.h#198
296     pub struct FbActivateFlags: u32 {
297         /// 立即设置值(或vbl)
298         const FB_ACTIVATE_NOW = 0;
299         /// 在下一次打开时激活
300         const FB_ACTIVATE_NXTOPEN = 1;
301         /// don't set, round up impossible values
302         const FB_ACTIVATE_TEST = 2;
303         const FB_ACTIVATE_MASK = 15;
304 
305         /// 在下一个vbl上激活值
306         const FB_ACTIVATE_VBL = 16;
307         /// 在vbl上更改色彩映射
308         const FB_ACTIVATE_CHANGE_CMAP_VBL = 32;
309         /// 更改此fb上的所有VC
310         const FB_ACTIVATE_ALL = 64;
311         /// 即使没有变化也强制应用
312         const FB_ACTIVATE_FORCE = 128;
313         /// 使视频模式无效
314         const FB_ACTIVATE_INV_MODE = 256;
315         /// 用于KDSET vt ioctl
316         const FB_ACTIVATE_KD_TEXT = 512;
317     }
318 }
319 
320 #[allow(dead_code)]
321 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
322 pub enum FbPixelFormat {
323     Standard,
324     /// Hold And Modify
325     HAM,
326     /// order of pixels in each byte is reversed
327     Reserved,
328 }
329 
330 bitflags! {
331     pub struct FbSyncFlags: u32 {
332         /// 水平同步高电平有效
333         const FB_SYNC_HOR_HIGH_ACT = 1;
334         /// 垂直同步高电平有效
335         const FB_SYNC_VERT_HIGH_ACT = 2;
336         /// 外部同步
337         const FB_SYNC_EXT = 4;
338         /// 复合同步高电平有效
339         const FB_SYNC_COMP_HIGH_ACT = 8;
340         /// 广播视频时序
341         const FB_SYNC_BROADCAST = 16;
342         /// sync on green
343         const FB_SYNC_ON_GREEN = 32;
344     }
345 }
346 
347 bitflags! {
348     /// `FbVModeFlags` 用于描述帧缓冲区的视频模式。
349     pub struct FbVModeFlags: u32 {
350         /// 非交错
351         const FB_VMODE_NONINTERLACED = 0;
352         /// 交错
353         const FB_VMODE_INTERLACED = 1;
354         /// 双扫描
355         const FB_VMODE_DOUBLE = 2;
356         /// 交错:首先是顶行
357         const FB_VMODE_ODD_FLD_FIRST = 4;
358         /// 掩码
359         const FB_VMODE_MASK = 255;
360         /// ywrap代替平移
361         const FB_VMODE_YWRAP = 256;
362         /// 平滑xpan可能(内部使用)
363         const FB_VMODE_SMOOTH_XPAN = 512;
364         /// 不更新x/yoffset
365         const FB_VMODE_CONUPDATE = 512;
366     }
367 }
368 
369 /// 视频颜色空间
370 #[allow(dead_code)]
371 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
372 pub enum V4l2Colorspace {
373     /// 默认颜色空间,即让驱动程序自行判断。只能用于视频捕获。
374     Default = 0,
375     /// SMPTE 170M:用于广播NTSC/PAL SDTV
376     Smpte170m = 1,
377     /// 过时的1998年前的SMPTE 240M HDTV标准,已被Rec 709取代
378     Smpte240m = 2,
379     /// Rec.709:用于HDTV
380     Rec709 = 3,
381     /// 已弃用,不要使用。没有驱动程序会返回这个。这是基于对bt878数据表的误解。
382     Bt878 = 4,
383     /// NTSC 1953颜色空间。只有在处理非常非常旧的NTSC录音时才有意义。已被SMPTE 170M取代。
384     System470M = 5,
385     /// EBU Tech 3213 PAL/SECAM颜色空间。
386     System470Bg = 6,
387     /// 实际上是V4L2_COLORSPACE_SRGB,V4L2_YCBCR_ENC_601和V4L2_QUANTIZATION_FULL_RANGE的简写。用于(Motion-)JPEG。
388     Jpeg = 7,
389     /// 用于RGB颜色空间,如大多数网络摄像头所产生的。
390     Srgb = 8,
391     /// opRGB颜色空间
392     Oprgb = 9,
393     /// BT.2020颜色空间,用于UHDTV。
394     Bt2020 = 10,
395     /// Raw颜色空间:用于RAW未处理的图像
396     Raw = 11,
397     /// DCI-P3颜色空间,用于电影投影机
398     DciP3 = 12,
399 
400     /// Largest supported colorspace value, assigned by the compiler, used
401     /// by the framework to check for invalid values.
402     Last,
403 }
404 
405 impl Default for V4l2Colorspace {
406     fn default() -> Self {
407         V4l2Colorspace::Default
408     }
409 }
410 
411 /// `FixedScreenInfo` 结构体用于描述屏幕的固定属性。
412 #[allow(dead_code)]
413 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
414 pub struct FixedScreenInfo {
415     // 字符串,用于标识屏幕,例如 "TT Builtin"
416     pub id: [char; 16],
417     // 帧缓冲区的起始物理地址
418     pub smem_start: PhysAddr,
419     // 帧缓冲区的长度
420     pub smem_len: u32,
421     // 屏幕类型,参考 FB_TYPE_
422     pub fb_type: FbType,
423     // 用于表示交错平面的小端辅助类型
424     pub type_aux: u32,
425     // 视觉类型,参考 FB_VISUAL_
426     pub visual: FbVisual,
427     // 水平缩放步长,如果无硬件缩放,则为0
428     pub xpanstep: u16,
429     // 垂直缩放步长,如果无硬件缩放,则为0
430     pub ypanstep: u16,
431     // 垂直环绕步长,如果无硬件环绕,则为0
432     pub ywrapstep: u16,
433     // 一行的大小(以字节为单位)
434     pub line_length: u32,
435     // 内存映射I/O的起始物理地址
436     pub mmio_start: PhysAddr,
437     // 内存映射I/O的长度
438     pub mmio_len: u32,
439     // 表示驱动器拥有的特定芯片/卡片类型
440     pub accel: u32,
441     // 表示支持的特性,参考 FB_CAP_
442     pub capabilities: FbCapability,
443 }
444 
445 /// 帧缓冲类型
446 #[allow(dead_code)]
447 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
448 pub enum FbType {
449     /// 压缩像素
450     PackedPixels = 0,
451     /// 非交错平面
452     Planes = 1,
453     /// 交错平面
454     InterleavedPlanes = 2,
455     /// 文本/属性
456     Text = 3,
457     /// EGA/VGA平面
458     VgaPlanes = 4,
459     /// 由V4L2 FOURCC标识的类型
460     FourCC = 5,
461 }
462 
463 /// 帧缓冲视觉类型
464 #[allow(dead_code)]
465 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
466 pub enum FbVisual {
467     /// 单色。1=黑色 0=白色
468     Mono01 = 0,
469     /// 单色。1=白色 0=黑色
470     Mono10 = 1,
471     /// 真彩色
472     TrueColor = 2,
473     /// 伪彩色(如Atari)
474     PseudoColor = 3,
475     /// 直接颜色
476     DirectColor = 4,
477     /// 只读的伪彩色
478     StaticPseudoColor = 5,
479     /// 由FOURCC标识的类型
480     FourCC,
481 }
482 
483 #[allow(dead_code)]
484 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
485 pub enum FbCapability {
486     Default = 0,
487     /// 设备支持基于FOURCC的格式。
488     FourCC,
489 }
490 
491 /// 视频模式
492 #[allow(dead_code)]
493 #[derive(Debug, Clone, Eq, PartialEq)]
494 pub struct FbVideoMode {
495     /// 可选的名称
496     pub name: Option<String>,
497     /// 可选的刷新率
498     pub refresh: Option<u32>,
499     /// 水平分辨率
500     pub xres: u32,
501     /// 垂直分辨率
502     pub yres: u32,
503     /// 像素时钟
504     pub pixclock: u32,
505     /// 左边距
506     pub left_margin: u32,
507     /// 右边距
508     pub right_margin: u32,
509     /// 上边距
510     pub upper_margin: u32,
511     /// 下边距
512     pub lower_margin: u32,
513     /// 水平同步长度
514     pub hsync_len: u32,
515     /// 垂直同步长度
516     pub vsync_len: u32,
517     /// 同步
518     pub sync: FbSyncFlags,
519     /// 视频模式
520     pub vmode: FbVModeFlags,
521     /// 标志
522     pub flag: u32,
523 }
524