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