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