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