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); 412 413 /// 将帧缓冲区的内容映射到用户空间。 414 fn fb_mmap(&self, _vma: &Arc<LockedVMA>) -> Result<(), SystemError> { 415 Err(SystemError::ENOSYS) 416 } 417 418 /// 卸载与该帧缓冲区相关的所有资源 419 fn fb_destroy(&self); 420 421 /// 画光标 422 fn fb_cursor(&self, _cursor: &FbCursor) -> Result<(), SystemError> { 423 return Err(SystemError::ENOSYS); 424 } 425 426 /// 画软光标(暂时简要实现) 427 fn soft_cursor(&self, cursor: FbCursor) -> Result<(), SystemError> { 428 let mut image = cursor.image.clone(); 429 if cursor.enable { 430 match cursor.rop { 431 true => { 432 for i in 0..image.data.len() { 433 image.data[i] ^= cursor.mask[i]; 434 } 435 } 436 false => { 437 for i in 0..image.data.len() { 438 image.data[i] &= cursor.mask[i]; 439 } 440 } 441 } 442 } 443 444 let _ = self.fb_image_blit(&image); 445 446 Ok(()) 447 } 448 449 fn fb_sync(&self) -> Result<(), SystemError> { 450 return Err(SystemError::ENOSYS); 451 } 452 453 /// 绘画位图 454 fn fb_image_blit(&self, image: &FbImage); 455 456 fn fb_set_color_map(&self, _cmap: Vec<Color>) -> Result<(), SystemError> { 457 return Err(SystemError::ENOSYS); 458 } 459 } 460 461 /// 帧缓冲区的状态 462 #[derive(Debug, Copy, Clone, Eq, PartialEq)] 463 pub enum FbState { 464 Running = 0, 465 Suspended = 1, 466 } 467 468 /// 屏幕黑屏模式。 469 #[allow(dead_code)] 470 #[derive(Debug, Copy, Clone, Eq, PartialEq)] 471 pub enum BlankMode { 472 /// 取消屏幕黑屏, 垂直同步和水平同步均打开 473 Unblank, 474 /// 屏幕黑屏, 垂直同步和水平同步均打开 475 Normal, 476 /// 屏幕黑屏, 水平同步打开, 垂直同步关闭 477 HSync, 478 /// 屏幕黑屏, 水平同步关闭, 垂直同步打开 479 VSync, 480 /// 屏幕黑屏, 水平同步和垂直同步均关闭 481 Powerdown, 482 } 483 484 /// `FillRectData` 结构体用于表示一个矩形区域并填充特定颜色。 485 /// 486 /// # 结构体字段 487 /// * `dx`: 488 /// * `dy`: 489 /// * `width`: 490 /// * `height`: 矩形的高度 491 /// * `color`: 用于填充矩形的颜色,是一个32位无符号整数 492 /// * `rop`: 光栅操作(Raster Operation),用于定义如何将颜色应用到矩形区域 493 #[derive(Debug, Copy, Clone, Eq, PartialEq)] 494 pub struct FillRectData { 495 /// 矩形左上角的x坐标(相对于屏幕) 496 pub dx: u32, 497 /// 矩形左上角的y坐标(相对于屏幕) 498 pub dy: u32, 499 /// 矩形的宽度 500 pub width: u32, 501 /// 矩形的高度 502 pub height: u32, 503 /// 用于填充矩形的颜色,是一个32位无符号整数 504 pub color: u32, 505 /// 光栅操作(Raster Operation),用于定义如何将颜色应用到矩形区域 506 pub rop: FillRectROP, 507 } 508 509 impl FillRectData { 510 #[allow(dead_code)] 511 pub fn new(dx: u32, dy: u32, width: u32, height: u32, color: u32, rop: FillRectROP) -> Self { 512 Self { 513 dx, 514 dy, 515 width, 516 height, 517 color, 518 rop, 519 } 520 } 521 } 522 523 /// 光栅操作(Raster Operation),用于定义如何将颜色应用到矩形区域 524 #[allow(dead_code)] 525 #[derive(Debug, Copy, Clone, Eq, PartialEq)] 526 pub enum FillRectROP { 527 /// 复制操作,即直接将指定颜色应用到矩形区域,覆盖原有颜色。 528 Copy, 529 /// 异或操作,即将指定颜色与矩形区域原有颜色进行异或操作,结果颜色应用到矩形区域。 530 Xor, 531 } 532 533 /// `CopyAreaData` 结构体用于表示一个矩形区域,并指定从哪个源位置复制数据。 534 /// 535 /// 注意,源位置必须是有意义的(即包围的矩形都必须得在屏幕内) 536 #[derive(Debug, Copy, Clone, Eq, PartialEq)] 537 pub struct CopyAreaData { 538 /// 目标矩形左上角的x坐标 539 pub dx: i32, 540 /// 目标矩形左上角的y坐标 541 pub dy: i32, 542 /// 矩形的宽度 543 pub width: u32, 544 /// 矩形的高度 545 pub height: u32, 546 /// 源矩形左上角的x坐标 547 pub sx: i32, 548 /// 源矩形左上角的y坐标 549 pub sy: i32, 550 } 551 552 impl CopyAreaData { 553 #[allow(dead_code)] 554 pub fn new(dx: i32, dy: i32, width: u32, height: u32, sx: i32, sy: i32) -> Self { 555 Self { 556 dx, 557 dy, 558 width, 559 height, 560 sx, 561 sy, 562 } 563 } 564 } 565 566 /// `FbVarScreenInfo` 结构体用于描述屏幕的各种属性。 567 #[derive(Debug, Copy, Clone, Eq, PartialEq)] 568 pub struct FbVarScreenInfo { 569 /// 可见分辨率的宽度 570 pub xres: u32, 571 /// 可见分辨率的高度 572 pub yres: u32, 573 /// 虚拟分辨率的宽度 574 pub xres_virtual: u32, 575 /// 虚拟分辨率的高度 576 pub yres_virtual: u32, 577 /// 从虚拟到可见分辨率的偏移量(宽度方向) 578 pub xoffset: u32, 579 /// 从虚拟到可见分辨率的偏移量(高度方向) 580 pub yoffset: u32, 581 /// 每像素的位数 582 pub bits_per_pixel: u32, 583 /// 颜色模式 584 pub color_mode: FbColorMode, 585 /// 红色位域 586 pub red: FbBitfield, 587 /// 绿色位域 588 pub green: FbBitfield, 589 /// 蓝色位域 590 pub blue: FbBitfield, 591 /// 透明度位域 592 pub transp: FbBitfield, 593 /// 像素格式 594 pub pixel_format: FbPixelFormat, 595 /// 激活标志(参见FB_ACTIVATE_*) 596 pub activate: FbActivateFlags, 597 /// 帧缓冲区的高度(像素) None表示未知 598 pub height: Option<u32>, 599 /// 帧缓冲区的宽度(像素) None表示未知 600 pub width: Option<u32>, 601 /// 像素时钟(皮秒) 602 pub pixclock: u32, 603 /// 左边距 604 pub left_margin: u32, 605 /// 右边距 606 pub right_margin: u32, 607 /// 上边距 608 pub upper_margin: u32, 609 /// 下边距 610 pub lower_margin: u32, 611 /// 水平同步的长度 612 pub hsync_len: u32, 613 /// 垂直同步的长度 614 pub vsync_len: u32, 615 /// 同步标志(参见FB_SYNC_*) 616 pub sync: FbSyncFlags, 617 /// 视频模式(参见FB_VMODE_*) 618 pub vmode: FbVModeFlags, 619 /// 逆时针旋转的角度 620 pub rotate_angle: u32, 621 /// 颜色空间 622 pub colorspace: V4l2Colorspace, 623 } 624 625 impl Default for FbVarScreenInfo { 626 fn default() -> Self { 627 Self { 628 xres: Default::default(), 629 yres: Default::default(), 630 xres_virtual: Default::default(), 631 yres_virtual: Default::default(), 632 xoffset: Default::default(), 633 yoffset: Default::default(), 634 bits_per_pixel: Default::default(), 635 color_mode: Default::default(), 636 red: Default::default(), 637 green: Default::default(), 638 blue: Default::default(), 639 transp: Default::default(), 640 pixel_format: Default::default(), 641 activate: Default::default(), 642 height: None, 643 width: None, 644 pixclock: Default::default(), 645 left_margin: Default::default(), 646 right_margin: Default::default(), 647 upper_margin: Default::default(), 648 lower_margin: Default::default(), 649 hsync_len: Default::default(), 650 vsync_len: Default::default(), 651 sync: FbSyncFlags::empty(), 652 vmode: FbVModeFlags::empty(), 653 rotate_angle: Default::default(), 654 colorspace: Default::default(), 655 } 656 } 657 } 658 659 /// 帧缓冲区的颜色模式 660 /// 661 /// 默认为彩色 662 #[allow(dead_code)] 663 #[derive(Debug, Copy, Clone, Eq, PartialEq)] 664 pub enum FbColorMode { 665 /// 灰度 666 GrayScale, 667 /// 彩色 668 Color, 669 /// FOURCC 670 FourCC, 671 } 672 673 impl Default for FbColorMode { 674 fn default() -> Self { 675 FbColorMode::Color 676 } 677 } 678 679 /// `FbBitfield` 结构体用于描述颜色字段的位域。 680 /// 681 /// 所有的偏移量都是从右边开始,位于一个精确为'bits_per_pixel'宽度的"像素"值内。 682 /// 一个像素之后是一个位流,并且未经修改地写入视频内存。 683 /// 684 /// 对于伪颜色:所有颜色组件的偏移和长度应该相同。 685 /// 偏移指定了调色板索引在像素值中的最低有效位的位置。 686 /// 长度表示可用的调色板条目的数量(即条目数 = 1 << 长度)。 687 #[derive(Debug, Copy, Clone, Eq, PartialEq)] 688 pub struct FbBitfield { 689 /// 位域的起始位置 690 pub offset: u32, 691 /// 位域的长度 692 pub length: u32, 693 /// 最高有效位是否在右边 694 pub msb_right: bool, 695 } 696 697 impl FbBitfield { 698 #[allow(dead_code)] 699 pub fn new(offset: u32, length: u32, msb_right: bool) -> Self { 700 Self { 701 offset, 702 length, 703 msb_right, 704 } 705 } 706 } 707 708 impl Default for FbBitfield { 709 fn default() -> Self { 710 Self { 711 offset: Default::default(), 712 length: Default::default(), 713 msb_right: Default::default(), 714 } 715 } 716 } 717 718 bitflags! { 719 /// `FbActivateFlags` 用于描述帧缓冲区的激活标志。 720 /// 721 /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/include/uapi/linux/fb.h#198 722 pub struct FbActivateFlags: u32 { 723 /// 立即设置值(或vbl) 724 const FB_ACTIVATE_NOW = 0; 725 /// 在下一次打开时激活 726 const FB_ACTIVATE_NXTOPEN = 1; 727 /// don't set, round up impossible values 728 const FB_ACTIVATE_TEST = 2; 729 const FB_ACTIVATE_MASK = 15; 730 731 /// 在下一个vbl上激活值 732 const FB_ACTIVATE_VBL = 16; 733 /// 在vbl上更改色彩映射 734 const FB_ACTIVATE_CHANGE_CMAP_VBL = 32; 735 /// 更改此fb上的所有VC 736 const FB_ACTIVATE_ALL = 64; 737 /// 即使没有变化也强制应用 738 const FB_ACTIVATE_FORCE = 128; 739 /// 使视频模式无效 740 const FB_ACTIVATE_INV_MODE = 256; 741 /// 用于KDSET vt ioctl 742 const FB_ACTIVATE_KD_TEXT = 512; 743 } 744 } 745 746 impl Default for FbActivateFlags { 747 fn default() -> Self { 748 FbActivateFlags::FB_ACTIVATE_NOW 749 } 750 } 751 752 #[allow(dead_code)] 753 #[derive(Debug, Copy, Clone, Eq, PartialEq)] 754 pub enum FbPixelFormat { 755 Standard, 756 /// Hold And Modify 757 HAM, 758 /// order of pixels in each byte is reversed 759 Reserved, 760 } 761 762 impl Default for FbPixelFormat { 763 fn default() -> Self { 764 FbPixelFormat::Standard 765 } 766 } 767 768 bitflags! { 769 pub struct FbSyncFlags: u32 { 770 /// 水平同步高电平有效 771 const FB_SYNC_HOR_HIGH_ACT = 1; 772 /// 垂直同步高电平有效 773 const FB_SYNC_VERT_HIGH_ACT = 2; 774 /// 外部同步 775 const FB_SYNC_EXT = 4; 776 /// 复合同步高电平有效 777 const FB_SYNC_COMP_HIGH_ACT = 8; 778 /// 广播视频时序 779 const FB_SYNC_BROADCAST = 16; 780 /// sync on green 781 const FB_SYNC_ON_GREEN = 32; 782 } 783 } 784 785 bitflags! { 786 /// `FbVModeFlags` 用于描述帧缓冲区的视频模式。 787 pub struct FbVModeFlags: u32 { 788 /// 非交错 789 const FB_VMODE_NONINTERLACED = 0; 790 /// 交错 791 const FB_VMODE_INTERLACED = 1; 792 /// 双扫描 793 const FB_VMODE_DOUBLE = 2; 794 /// 交错:首先是顶行 795 const FB_VMODE_ODD_FLD_FIRST = 4; 796 /// 掩码 797 const FB_VMODE_MASK = 255; 798 /// ywrap代替平移 799 const FB_VMODE_YWRAP = 256; 800 /// 平滑xpan可能(内部使用) 801 const FB_VMODE_SMOOTH_XPAN = 512; 802 /// 不更新x/yoffset 803 const FB_VMODE_CONUPDATE = 512; 804 } 805 } 806 807 /// 视频颜色空间 808 #[allow(dead_code)] 809 #[derive(Debug, Copy, Clone, Eq, PartialEq)] 810 pub enum V4l2Colorspace { 811 /// 默认颜色空间,即让驱动程序自行判断。只能用于视频捕获。 812 Default = 0, 813 /// SMPTE 170M:用于广播NTSC/PAL SDTV 814 Smpte170m = 1, 815 /// 过时的1998年前的SMPTE 240M HDTV标准,已被Rec 709取代 816 Smpte240m = 2, 817 /// Rec.709:用于HDTV 818 Rec709 = 3, 819 /// 已弃用,不要使用。没有驱动程序会返回这个。这是基于对bt878数据表的误解。 820 Bt878 = 4, 821 /// NTSC 1953颜色空间。只有在处理非常非常旧的NTSC录音时才有意义。已被SMPTE 170M取代。 822 System470M = 5, 823 /// EBU Tech 3213 PAL/SECAM颜色空间。 824 System470Bg = 6, 825 /// 实际上是V4L2_COLORSPACE_SRGB,V4L2_YCBCR_ENC_601和V4L2_QUANTIZATION_FULL_RANGE的简写。用于(Motion-)JPEG。 826 Jpeg = 7, 827 /// 用于RGB颜色空间,如大多数网络摄像头所产生的。 828 Srgb = 8, 829 /// opRGB颜色空间 830 Oprgb = 9, 831 /// BT.2020颜色空间,用于UHDTV。 832 Bt2020 = 10, 833 /// Raw颜色空间:用于RAW未处理的图像 834 Raw = 11, 835 /// DCI-P3颜色空间,用于电影投影机 836 DciP3 = 12, 837 838 /// Largest supported colorspace value, assigned by the compiler, used 839 /// by the framework to check for invalid values. 840 Last, 841 } 842 843 impl Default for V4l2Colorspace { 844 fn default() -> Self { 845 V4l2Colorspace::Default 846 } 847 } 848 849 /// `FixedScreenInfo` 结构体用于描述屏幕的固定属性。 850 #[allow(dead_code)] 851 #[derive(Debug, Copy, Clone, Eq, PartialEq)] 852 pub struct FixedScreenInfo { 853 // 字符串,用于标识屏幕,例如 "TT Builtin" 854 pub id: [char; 16], 855 // 帧缓冲区的起始物理地址 856 pub smem_start: Option<PhysAddr>, 857 // 帧缓冲区的长度 858 pub smem_len: usize, 859 // 屏幕类型,参考 FB_TYPE_ 860 pub fb_type: FbType, 861 // 用于表示交错平面的小端辅助类型 862 pub type_aux: u32, 863 // 视觉类型,参考 FB_VISUAL_ 864 pub visual: FbVisual, 865 // 水平缩放步长,如果无硬件缩放,则为0 866 pub xpanstep: u16, 867 // 垂直缩放步长,如果无硬件缩放,则为0 868 pub ypanstep: u16, 869 // 垂直环绕步长,如果无硬件环绕,则为0 870 pub ywrapstep: u16, 871 // 一行的大小(以字节为单位) 872 pub line_length: u32, 873 // 内存映射I/O端口的起始物理地址 874 pub mmio_start: Option<PhysAddr>, 875 // 内存映射I/O的长度 876 pub mmio_len: usize, 877 // 表示驱动器拥有的特定芯片/卡片类型 878 pub accel: FbAccel, 879 // 表示支持的特性,参考 FB_CAP_ 880 pub capabilities: FbCapability, 881 } 882 883 impl FixedScreenInfo { 884 /// 将字符串转换为长度为16的字符数组(包含结尾的`\0`) 885 /// 886 /// ## 参数 887 /// 888 /// - `name`: 字符串,长度不超过15,超过的部分将被截断 889 /// 890 /// ## 返回 891 /// 892 /// 长度为16的字符数组 893 pub const fn name2id(name: &str) -> [char; 16] { 894 let mut id = [0 as char; 16]; 895 let mut i = 0; 896 897 while i < 15 && i < name.len() { 898 id[i] = name.as_bytes()[i] as char; 899 i += 1; 900 } 901 902 id[i] = '\0'; 903 return id; 904 } 905 } 906 907 impl Default for FixedScreenInfo { 908 fn default() -> Self { 909 Self { 910 id: Default::default(), 911 smem_start: None, 912 smem_len: Default::default(), 913 fb_type: FbType::PackedPixels, 914 type_aux: Default::default(), 915 visual: FbVisual::Mono10, 916 xpanstep: Default::default(), 917 ypanstep: Default::default(), 918 ywrapstep: Default::default(), 919 line_length: Default::default(), 920 mmio_start: None, 921 mmio_len: Default::default(), 922 accel: Default::default(), 923 capabilities: Default::default(), 924 } 925 } 926 } 927 928 /// 帧缓冲类型 929 #[allow(dead_code)] 930 #[derive(Debug, Copy, Clone, Eq, PartialEq)] 931 pub enum FbType { 932 /// 压缩像素 933 PackedPixels = 0, 934 /// 非交错平面 935 Planes = 1, 936 /// 交错平面 937 InterleavedPlanes = 2, 938 /// 文本/属性 939 Text = 3, 940 /// EGA/VGA平面 941 VgaPlanes = 4, 942 /// 由V4L2 FOURCC标识的类型 943 FourCC = 5, 944 } 945 946 /// 帧缓冲视觉类型 947 #[allow(dead_code)] 948 #[derive(Debug, Copy, Clone, Eq, PartialEq)] 949 pub enum FbVisual { 950 /// 单色。1=黑色 0=白色 951 Mono01 = 0, 952 /// 单色。1=白色 0=黑色 953 Mono10 = 1, 954 /// 真彩色 955 TrueColor = 2, 956 /// 伪彩色(如Atari) 957 PseudoColor = 3, 958 /// 直接颜色 959 DirectColor = 4, 960 /// 只读的伪彩色 961 StaticPseudoColor = 5, 962 /// 由FOURCC标识的类型 963 FourCC, 964 } 965 966 #[allow(dead_code)] 967 #[derive(Debug, Copy, Clone, Eq, PartialEq)] 968 pub enum FbCapability { 969 Default = 0, 970 /// 设备支持基于FOURCC的格式。 971 FourCC, 972 } 973 974 impl Default for FbCapability { 975 fn default() -> Self { 976 FbCapability::Default 977 } 978 } 979 980 /// 视频模式 981 #[allow(dead_code)] 982 #[derive(Debug, Clone, Eq, PartialEq)] 983 pub struct FbVideoMode { 984 /// 可选的名称 985 pub name: Option<String>, 986 /// 可选的刷新率 987 pub refresh: Option<u32>, 988 /// 水平分辨率 989 pub xres: u32, 990 /// 垂直分辨率 991 pub yres: u32, 992 /// 像素时钟 993 pub pixclock: u32, 994 /// 左边距 995 pub left_margin: u32, 996 /// 右边距 997 pub right_margin: u32, 998 /// 上边距 999 pub upper_margin: u32, 1000 /// 下边距 1001 pub lower_margin: u32, 1002 /// 水平同步长度 1003 pub hsync_len: u32, 1004 /// 垂直同步长度 1005 pub vsync_len: u32, 1006 /// 同步 1007 pub sync: FbSyncFlags, 1008 /// 视频模式 1009 pub vmode: FbVModeFlags, 1010 /// 标志 1011 pub flag: u32, 1012 } 1013 1014 #[allow(dead_code)] 1015 #[derive(Debug, Copy, Clone, Eq, PartialEq)] 1016 pub enum FbAccel { 1017 /// 没有硬件加速器 1018 None, 1019 1020 AtariBlitter = 1, 1021 AmigaBlitter = 2, 1022 S3Trio64 = 3, 1023 NCR77C32BLT = 4, 1024 S3Virge = 5, 1025 AtiMach64GX = 6, 1026 DECTGA = 7, 1027 AtiMach64CT = 8, 1028 AtiMach64VT = 9, 1029 AtiMach64GT = 10, 1030 SunCreator = 11, 1031 SunCGSix = 12, 1032 SunLeo = 13, 1033 IMSTwinTurbo = 14, 1034 Acc3DLabsPermedia2 = 15, 1035 MatroxMGA2064W = 16, 1036 MatroxMGA1064SG = 17, 1037 MatroxMGA2164W = 18, 1038 MatroxMGA2164WAGP = 19, 1039 MatroxMGAG400 = 20, 1040 NV3 = 21, 1041 NV4 = 22, 1042 NV5 = 23, 1043 NV6 = 24, 1044 XGIVolariV = 25, 1045 XGIVolariZ = 26, 1046 Omap1610 = 27, 1047 TridentTGUI = 28, 1048 Trident3DImage = 29, 1049 TridentBlade3D = 30, 1050 TridentBladeXP = 31, 1051 CirrusAlpine = 32, 1052 NeoMagicNM2070 = 90, 1053 NeoMagicNM2090 = 91, 1054 NeoMagicNM2093 = 92, 1055 NeoMagicNM2097 = 93, 1056 NeoMagicNM2160 = 94, 1057 NeoMagicNM2200 = 95, 1058 NeoMagicNM2230 = 96, 1059 NeoMagicNM2360 = 97, 1060 NeoMagicNM2380 = 98, 1061 PXA3XX = 99, 1062 1063 Savage4 = 0x80, 1064 Savage3D = 0x81, 1065 Savage3DMV = 0x82, 1066 Savage2000 = 0x83, 1067 SavageMXMV = 0x84, 1068 SavageMX = 0x85, 1069 SavageIXMV = 0x86, 1070 SavageIX = 0x87, 1071 ProSavagePM = 0x88, 1072 ProSavageKM = 0x89, 1073 S3Twister = 0x8a, 1074 S3TwisterK = 0x8b, 1075 SuperSavage = 0x8c, 1076 ProSavageDDR = 0x8d, 1077 ProSavageDDRK = 0x8e, 1078 // Add other accelerators here 1079 } 1080 1081 impl Default for FbAccel { 1082 fn default() -> Self { 1083 FbAccel::None 1084 } 1085 } 1086 1087 #[derive(Debug, Copy, Clone)] 1088 pub struct BootTimeScreenInfo { 1089 pub origin_x: u8, 1090 pub origin_y: u8, 1091 /// text mode时,每行的字符数 1092 pub origin_video_cols: u8, 1093 /// text mode时,行数 1094 pub origin_video_lines: u8, 1095 /// 标记屏幕是否为VGA类型 1096 pub is_vga: bool, 1097 /// video mode type 1098 pub video_type: BootTimeVideoType, 1099 1100 // 以下字段用于线性帧缓冲区 1101 /// 线性帧缓冲区的起始物理地址 1102 pub lfb_base: PhysAddr, 1103 /// 线性帧缓冲区在初始化阶段被映射到的起始虚拟地址 1104 /// 1105 /// 这个值可能会被设置2次: 1106 /// 1107 /// - 内存管理初始化之前,early init阶段,临时映射 1108 /// - 内存管理初始化完毕,重新映射时被设置 1109 pub lfb_virt_base: Option<VirtAddr>, 1110 /// 线性帧缓冲区的长度 1111 pub lfb_size: usize, 1112 /// 线性帧缓冲区的宽度(像素) 1113 pub lfb_width: u32, 1114 /// 线性帧缓冲区的高度(像素) 1115 pub lfb_height: u32, 1116 /// 线性帧缓冲区的深度(位数) 1117 pub lfb_depth: u8, 1118 /// 红色位域的大小 1119 pub red_size: u8, 1120 /// 红色位域的偏移量(左移位数) 1121 pub red_pos: u8, 1122 /// 绿色位域的大小 1123 pub green_size: u8, 1124 /// 绿色位域的偏移量(左移位数) 1125 pub green_pos: u8, 1126 /// 蓝色位域的大小 1127 pub blue_size: u8, 1128 /// 蓝色位域的偏移量(左移位数) 1129 pub blue_pos: u8, 1130 } 1131 1132 impl BootTimeScreenInfo { 1133 pub const DEFAULT: Self = Self { 1134 origin_x: 0, 1135 origin_y: 0, 1136 is_vga: false, 1137 lfb_base: PhysAddr::new(0), 1138 lfb_size: 0, 1139 lfb_width: 0, 1140 lfb_height: 0, 1141 red_size: 0, 1142 red_pos: 0, 1143 green_size: 0, 1144 green_pos: 0, 1145 blue_size: 0, 1146 blue_pos: 0, 1147 video_type: BootTimeVideoType::UnDefined, 1148 origin_video_cols: 0, 1149 origin_video_lines: 0, 1150 lfb_virt_base: None, 1151 lfb_depth: 0, 1152 }; 1153 } 1154 1155 /// Video types for different display hardware 1156 #[allow(dead_code)] 1157 #[derive(Debug, Copy, Clone, Eq, PartialEq)] 1158 pub enum BootTimeVideoType { 1159 UnDefined, 1160 /// Monochrome Text Display 1161 Mda, 1162 /// CGA Display 1163 Cga, 1164 /// EGA/VGA in Monochrome Mode 1165 EgaM, 1166 /// EGA in Color Mode 1167 EgaC, 1168 /// VGA+ in Color Mode 1169 VgaC, 1170 /// VESA VGA in graphic mode 1171 Vlfb, 1172 /// ACER PICA-61 local S3 video 1173 PicaS3, 1174 /// MIPS Magnum 4000 G364 video 1175 MipsG364, 1176 /// Various SGI graphics hardware 1177 Sgi, 1178 /// DEC TGA 1179 TgaC, 1180 /// Sun frame buffer 1181 Sun, 1182 /// Sun PCI based frame buffer 1183 SunPci, 1184 /// PowerMacintosh frame buffer 1185 Pmac, 1186 /// EFI graphic mode 1187 Efi, 1188 } 1189 1190 #[derive(Debug, Default)] 1191 pub struct FbCursor { 1192 /// 设置选项 1193 pub set_mode: FbCursorSetMode, 1194 /// 开关选项 1195 pub enable: bool, 1196 /// 表示光标图像的位操作,true表示XOR,false表示COPY 1197 pub rop: bool, 1198 /// 表示光标掩码(mask)的数据。掩码用于定义光标的形状,指定了哪些像素是光标的一部分。 1199 pub mask: Vec<u8>, 1200 1201 /// 表示光标的热点位置,即在光标图像中被认为是"焦点"的位置 1202 pub hot_x: u32, 1203 pub hot_y: u32, 1204 1205 /// 光标图像 1206 pub image: FbImage, 1207 } 1208 1209 bitflags! { 1210 /// 硬件光标控制 1211 #[derive(Default)] 1212 pub struct FbCursorSetMode:u8 { 1213 /// 设置位图 1214 const FB_CUR_SETIMAGE = 0x01; 1215 /// 设置位置 1216 const FB_CUR_SETPOS = 0x02; 1217 /// 设置热点 1218 const FB_CUR_SETHOT = 0x04; 1219 /// ColorMap 1220 const FB_CUR_SETCMAP = 0x08; 1221 /// 形状 1222 const FB_CUR_SETSHAPE = 0x10; 1223 /// Size 1224 const FB_CUR_SETSIZE = 0x20; 1225 /// 全设置 1226 const FB_CUR_SETALL = 0xFF; 1227 } 1228 } 1229 1230 #[allow(dead_code)] 1231 #[derive(Debug, Clone, Copy)] 1232 pub enum ScrollMode { 1233 Move, 1234 PanMove, 1235 WrapMove, 1236 Redraw, 1237 PanRedraw, 1238 } 1239 1240 impl Default for ScrollMode { 1241 /// ## 默认Move 1242 fn default() -> Self { 1243 Self::Move 1244 } 1245 } 1246 1247 #[derive(Debug, Default, Clone)] 1248 pub struct FbImage { 1249 pub x: u32, 1250 pub y: u32, 1251 pub width: u32, 1252 pub height: u32, 1253 pub fg: u32, 1254 pub bg: u32, 1255 pub depth: u8, 1256 pub data: Vec<u8>, 1257 } 1258