1 use alloc::{string::String, sync::Arc, vec::Vec}; 2 use render_helper::{FrameP, FramePointerStatus}; 3 use system_error::SystemError; 4 5 use crate::{ 6 driver::{base::device::Device, tty::virtual_terminal::Color}, 7 init::boot_params, 8 libs::rwlock::RwLock, 9 mm::{ucontext::LockedVMA, PhysAddr, VirtAddr}, 10 }; 11 12 use self::{ 13 fbmem::{FbDevice, FrameBufferManager}, 14 render_helper::{BitIter, EndianPattern}, 15 }; 16 17 const COLOR_TABLE_8: &[u32] = &[ 18 0x00000000, 0xff000000, 0x00ff0000, 0xffff0000, 0x0000ff00, 0xff00ff00, 0x00ffff00, 0xffffff00, 19 0x000000ff, 0xff0000ff, 0x00ff00ff, 0xffff00ff, 0x0000ffff, 0xff00ffff, 0x00ffffff, 0xffffffff, 20 ]; 21 22 const COLOR_TABLE_16: &[u32] = &[0x00000000, 0xffff0000, 0x0000ffff, 0xffffffff]; 23 24 const COLOR_TABLE_32: &[u32] = &[0x00000000, 0xffffffff]; 25 26 pub mod fbcon; 27 pub mod fbmem; 28 pub mod fbsysfs; 29 pub mod modedb; 30 pub mod render_helper; 31 // 帧缓冲区id 32 int_like!(FbId, u32); 33 34 lazy_static! { 35 pub static ref FRAME_BUFFER_SET: RwLock<Vec<Option<Arc<dyn FrameBuffer>>>> = { 36 let mut ret = Vec::new(); 37 ret.resize(FrameBufferManager::FB_MAX, None); 38 RwLock::new(ret) 39 }; 40 } 41 42 impl FbId { 43 /// 帧缓冲区id的初始值(无效值) 44 pub const INIT: Self = Self::new(u32::MAX); 45 46 /// 判断是否为无效的帧缓冲区id 47 #[allow(dead_code)] is_valid(&self) -> bool48 pub const fn is_valid(&self) -> bool { 49 if self.0 == Self::INIT.0 || self.0 >= FrameBufferManager::FB_MAX as u32 { 50 return false; 51 } 52 return true; 53 } 54 } 55 56 /// 帧缓冲区应该实现的接口 57 pub trait FrameBuffer: FrameBufferInfo + FrameBufferOps + Device { 58 /// 获取帧缓冲区的id fb_id(&self) -> FbId59 fn fb_id(&self) -> FbId; 60 61 /// 设置帧缓冲区的id set_fb_id(&self, id: FbId)62 fn set_fb_id(&self, id: FbId); 63 64 /// 通用的软件图像绘画 generic_imageblit(&self, image: &FbImage)65 fn generic_imageblit(&self, image: &FbImage) { 66 let boot_param = boot_params().read(); 67 let x = image.x; 68 let y = image.y; 69 let byte_per_pixel = core::mem::size_of::<u32>() as u32; 70 let bit_per_pixel = self.current_fb_var().bits_per_pixel; 71 72 // 计算图像在帧缓冲中的起始位 73 let bitstart = (y * self.current_fb_fix().line_length * 8) + (x * bit_per_pixel); 74 let start_index = bitstart & (32 - 1); 75 let pitch_index = (self.current_fb_fix().line_length & (byte_per_pixel - 1)) * 8; 76 let dst2 = boot_param.screen_info.lfb_virt_base; 77 if dst2.is_none() { 78 return; 79 } 80 let mut safe_pointer = FrameP::new( 81 self.current_fb_var().yres as usize, 82 self.current_fb_var().xres as usize, 83 self.current_fb_var().bits_per_pixel as usize, 84 dst2.unwrap(), 85 image, 86 ); 87 let _ = self.fb_sync(); 88 89 if image.depth == 1 { 90 let fg; 91 let bg; 92 if self.current_fb_fix().visual == FbVisual::TrueColor 93 || self.current_fb_fix().visual == FbVisual::DirectColor 94 { 95 let fb_info_data = self.framebuffer_info_data().read(); 96 fg = fb_info_data.pesudo_palette[image.fg as usize]; 97 bg = fb_info_data.pesudo_palette[image.bg as usize]; 98 } else { 99 fg = image.fg; 100 bg = image.bg; 101 } 102 103 if 32 % bit_per_pixel == 0 104 && start_index == 0 105 && pitch_index == 0 106 && image.width & (32 / bit_per_pixel - 1) == 0 107 && (8..=32).contains(&bit_per_pixel) 108 { 109 unsafe { self.fast_imageblit(image, &mut safe_pointer, fg, bg) } 110 } else { 111 self.slow_imageblit(image, &mut safe_pointer, fg, bg) 112 } 113 } else { 114 todo!("color image blit todo"); 115 } 116 } 117 118 /// 优化的单色图像绘制函数 119 /// 120 /// 仅当 bits_per_pixel 为 8、16 或 32 时才能使用。 121 /// 要求 image->width 可以被像素或 dword (ppw) 整除。 122 /// 要求 fix->line_length 可以被 4 整除。 123 /// 扫描线的开始和结束都是 dword 对齐的。 fast_imageblit(&self, image: &FbImage, dst1: &mut FrameP, fg: u32, bg: u32)124 unsafe fn fast_imageblit(&self, image: &FbImage, dst1: &mut FrameP, fg: u32, bg: u32) { 125 let bpp = self.current_fb_var().bits_per_pixel; 126 let mut fgx = fg; 127 let mut bgx = bg; 128 let ppw = 32 / bpp; 129 let spitch = (image.width + 7) / 8; 130 let mut color_tab: [u32; 16] = [0; 16]; 131 132 let tab: &[u32] = match bpp { 133 8 => COLOR_TABLE_8, 134 16 => COLOR_TABLE_16, 135 32 => COLOR_TABLE_32, 136 _ => { 137 return; 138 } 139 }; 140 141 for _ in (0..(ppw - 1)).rev() { 142 fgx <<= bpp; 143 bgx <<= bpp; 144 fgx |= fg; 145 bgx |= bg; 146 } 147 148 let bitmask = (1 << ppw) - 1; 149 let eorx = fgx ^ bgx; 150 let k = image.width / ppw; 151 152 for (idx, val) in tab.iter().enumerate() { 153 color_tab[idx] = (*val & eorx) ^ bgx; 154 } 155 156 let mut shift; 157 let mut src; 158 let mut offset = 0; 159 let mut j = 0; 160 let mut count = 0; 161 for _ in (0..image.height).rev() { 162 shift = 8; 163 src = offset; 164 match ppw { 165 4 => { 166 // 8bpp 167 j = k; 168 while j >= 2 { 169 dst1.write(color_tab[(image.data[src] as usize >> 4) & bitmask]); 170 dst1.write(color_tab[(image.data[src] as usize) & bitmask]); 171 j -= 2; 172 src += 1; 173 } 174 } 175 2 => { 176 // 16bpp 177 j = k; 178 while j >= 4 { 179 dst1.write(color_tab[(image.data[src] as usize >> 6) & bitmask]); 180 dst1.write(color_tab[(image.data[src] as usize >> 4) & bitmask]); 181 dst1.write(color_tab[(image.data[src] as usize >> 2) & bitmask]); 182 dst1.write(color_tab[(image.data[src] as usize) & bitmask]); 183 src += 1; 184 j -= 4; 185 } 186 } 187 1 => { 188 // 32 bpp 189 j = k; 190 while j >= 8 { 191 dst1.write(color_tab[(image.data[src] as usize >> 7) & bitmask]); 192 dst1.write(color_tab[(image.data[src] as usize >> 6) & bitmask]); 193 dst1.write(color_tab[(image.data[src] as usize >> 5) & bitmask]); 194 dst1.write(color_tab[(image.data[src] as usize >> 4) & bitmask]); 195 dst1.write(color_tab[(image.data[src] as usize >> 3) & bitmask]); 196 dst1.write(color_tab[(image.data[src] as usize >> 2) & bitmask]); 197 dst1.write(color_tab[(image.data[src] as usize >> 1) & bitmask]); 198 dst1.write(color_tab[(image.data[src] as usize) & bitmask]); 199 src += 1; 200 j -= 8; 201 } 202 } 203 _ => {} 204 } 205 206 /* 207 * For image widths that are not a multiple of 8, there 208 * are trailing pixels left on the current line. Print 209 * them as well. 210 */ 211 while j != 0 { 212 shift -= ppw; 213 dst1.write(color_tab[(image.data[src] as usize >> shift) & bitmask]); 214 if shift == 0 { 215 shift = 8; 216 src += 1; 217 } 218 j -= 1; 219 } 220 221 count += 1; 222 dst1.move_with_offset(self.current_fb_fix().line_length * count); 223 offset += spitch as usize; 224 } 225 } 226 slow_imageblit(&self, _image: &FbImage, safe_dst: &mut FrameP, _fg: u32, _bg: u32)227 fn slow_imageblit(&self, _image: &FbImage, safe_dst: &mut FrameP, _fg: u32, _bg: u32) { 228 let mut count = 0; 229 let mut pt_status = FramePointerStatus::Normal; 230 let iter = BitIter::new( 231 _fg, 232 _bg, 233 EndianPattern::Big, 234 EndianPattern::Little, 235 self.current_fb_var().bits_per_pixel / 8, 236 _image.data.iter(), 237 _image.width, 238 ); 239 for (content, full) in iter { 240 match pt_status { 241 FramePointerStatus::OutOfBuffer => { 242 return; 243 } 244 FramePointerStatus::OutOfScreen => {} 245 FramePointerStatus::Normal => { 246 pt_status = safe_dst.write(content); 247 } 248 } 249 if full { 250 count += 1; 251 safe_dst.move_with_offset(self.current_fb_fix().line_length * count); 252 pt_status = FramePointerStatus::Normal; 253 } 254 } 255 } 256 } 257 258 #[derive(Debug, Default)] 259 pub struct FrameBufferInfoData { 260 /// 颜色映射 261 pub color_map: Vec<Color>, 262 /// 颜色映射表 263 pub pesudo_palette: Vec<u32>, 264 } 265 266 impl FrameBufferInfoData { new() -> Self267 pub fn new() -> Self { 268 Self { 269 ..Default::default() 270 } 271 } 272 } 273 274 /// 帧缓冲区信息 275 #[allow(dead_code)] 276 pub trait FrameBufferInfo: FrameBufferOps { framebuffer_info_data(&self) -> &RwLock<FrameBufferInfoData>277 fn framebuffer_info_data(&self) -> &RwLock<FrameBufferInfoData>; 278 279 /// Amount of ioremapped VRAM or 0 screen_size(&self) -> usize280 fn screen_size(&self) -> usize; 281 282 /// 获取当前的可变帧缓冲信息 current_fb_var(&self) -> FbVarScreenInfo283 fn current_fb_var(&self) -> FbVarScreenInfo; 284 285 /// 获取当前的固定帧缓冲信息 current_fb_fix(&self) -> FixedScreenInfo286 fn current_fb_fix(&self) -> FixedScreenInfo; 287 288 /// 获取当前的视频模式 video_mode(&self) -> Option<&FbVideoMode>289 fn video_mode(&self) -> Option<&FbVideoMode>; 290 291 /// 获取当前帧缓冲区对应的`/sys/class/graphics/fb0`或者`/sys/class/graphics/fb1`等的设备结构体 fb_device(&self) -> Option<Arc<FbDevice>>292 fn fb_device(&self) -> Option<Arc<FbDevice>>; 293 294 /// 设置当前帧缓冲区对应的`/sys/class/graphics/fb0`或者`/sys/class/graphics/fb1`等的设备结构体 set_fb_device(&self, device: Option<Arc<FbDevice>>)295 fn set_fb_device(&self, device: Option<Arc<FbDevice>>); 296 297 /// 获取帧缓冲区的状态 state(&self) -> FbState298 fn state(&self) -> FbState; 299 300 /// 颜色位深 color_depth(&self) -> u32301 fn color_depth(&self) -> u32 { 302 return 8; 303 304 // 以下逻辑没问题,但是当前没有初始化好var,所以先直接返回当前vasafb的8 305 306 // let var = self.current_fb_var(); 307 // let fix = self.current_fb_fix(); 308 // if fix.visual == FbVisual::Mono01 || fix.visual == FbVisual::Mono10 { 309 // return 1; 310 // } else { 311 // if var.green.length == var.blue.length 312 // && var.green.length == var.red.length 313 // && var.green.offset == var.blue.offset 314 // && var.green.offset == var.red.offset 315 // { 316 // error!("return {}", var.green.length); 317 // return var.green.length; 318 // } else { 319 // return var.green.length + var.blue.length + var.red.length; 320 // } 321 // } 322 } 323 324 /// ## 设置调色板 set_color_map(&self, cmap: Vec<Color>) -> Result<(), SystemError>325 fn set_color_map(&self, cmap: Vec<Color>) -> Result<(), SystemError> { 326 let ret = self.fb_set_color_map(cmap.clone()); 327 if ret.is_err() && ret.clone().unwrap_err() == SystemError::ENOSYS { 328 for (idx, color) in cmap.iter().enumerate() { 329 if self 330 .fb_set_color_register(idx as u16, color.red, color.green, color.blue) 331 .is_err() 332 { 333 break; 334 } 335 } 336 337 self.framebuffer_info_data().write().color_map = cmap; 338 } else { 339 if ret.is_ok() { 340 self.framebuffer_info_data().write().color_map = cmap; 341 } 342 return ret; 343 } 344 345 Ok(()) 346 } 347 } 348 349 /// 帧缓冲区操作 350 /// 351 /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/fb.h#237 352 #[allow(dead_code)] 353 pub trait FrameBufferOps { fb_open(&self, user: bool)354 fn fb_open(&self, user: bool); fb_release(&self, user: bool)355 fn fb_release(&self, user: bool); 356 357 /// 读取帧缓冲区的内容。 358 /// 359 /// 对于具有奇特非线性布局的帧缓冲区或正常内存映射访问无法工作的帧缓冲区,可以使用此方法。 fb_read(&self, _buf: &mut [u8], _pos: usize) -> Result<usize, SystemError>360 fn fb_read(&self, _buf: &mut [u8], _pos: usize) -> Result<usize, SystemError> { 361 Err(SystemError::ENOSYS) 362 } 363 364 /// 将帧缓冲区的内容写入。 365 /// 366 /// 对于具有奇特非线性布局的帧缓冲区或正常内存映射访问无法工作的帧缓冲区,可以使用此方法。 fb_write(&self, _buf: &[u8], _pos: usize) -> Result<usize, SystemError>367 fn fb_write(&self, _buf: &[u8], _pos: usize) -> Result<usize, SystemError> { 368 Err(SystemError::ENOSYS) 369 } 370 371 /// 设置帧缓冲区的颜色寄存器。 372 /// 373 /// 颜色寄存器的数量和含义取决于帧缓冲区的硬件。 374 /// 375 /// ## 参数 376 /// 377 /// - `regno`:寄存器编号。 378 /// - `red`:红色分量。 379 /// - `green`:绿色分量。 380 /// - `blue`:蓝色分量。 fb_set_color_register( &self, regno: u16, red: u16, green: u16, blue: u16, ) -> Result<(), SystemError>381 fn fb_set_color_register( 382 &self, 383 regno: u16, 384 red: u16, 385 green: u16, 386 blue: u16, 387 ) -> Result<(), SystemError>; 388 389 /// 设置帧缓冲区的黑屏模式 fb_blank(&self, blank_mode: BlankMode) -> Result<(), SystemError>390 fn fb_blank(&self, blank_mode: BlankMode) -> Result<(), SystemError>; 391 392 /// 在帧缓冲区中绘制一个矩形。 fb_fillrect(&self, _data: FillRectData) -> Result<(), SystemError>393 fn fb_fillrect(&self, _data: FillRectData) -> Result<(), SystemError> { 394 Err(SystemError::ENOSYS) 395 } 396 397 /// 将数据从一处复制到另一处。 fb_copyarea(&self, _data: CopyAreaData)398 fn fb_copyarea(&self, _data: CopyAreaData); 399 400 /// 将帧缓冲区的内容映射到用户空间。 fb_mmap(&self, _vma: &Arc<LockedVMA>) -> Result<(), SystemError>401 fn fb_mmap(&self, _vma: &Arc<LockedVMA>) -> Result<(), SystemError> { 402 Err(SystemError::ENOSYS) 403 } 404 405 /// 卸载与该帧缓冲区相关的所有资源 fb_destroy(&self)406 fn fb_destroy(&self); 407 408 /// 画光标 fb_cursor(&self, _cursor: &FbCursor) -> Result<(), SystemError>409 fn fb_cursor(&self, _cursor: &FbCursor) -> Result<(), SystemError> { 410 return Err(SystemError::ENOSYS); 411 } 412 413 /// 画软光标(暂时简要实现) soft_cursor(&self, cursor: FbCursor) -> Result<(), SystemError>414 fn soft_cursor(&self, cursor: FbCursor) -> Result<(), SystemError> { 415 let mut image = cursor.image.clone(); 416 if cursor.enable { 417 match cursor.rop { 418 true => { 419 for i in 0..image.data.len() { 420 image.data[i] ^= cursor.mask[i]; 421 } 422 } 423 false => { 424 for i in 0..image.data.len() { 425 image.data[i] &= cursor.mask[i]; 426 } 427 } 428 } 429 } 430 431 self.fb_image_blit(&image); 432 433 Ok(()) 434 } 435 fb_sync(&self) -> Result<(), SystemError>436 fn fb_sync(&self) -> Result<(), SystemError> { 437 return Err(SystemError::ENOSYS); 438 } 439 440 /// 绘画位图 fb_image_blit(&self, image: &FbImage)441 fn fb_image_blit(&self, image: &FbImage); 442 fb_set_color_map(&self, _cmap: Vec<Color>) -> Result<(), SystemError>443 fn fb_set_color_map(&self, _cmap: Vec<Color>) -> Result<(), SystemError> { 444 return Err(SystemError::ENOSYS); 445 } 446 } 447 448 /// 帧缓冲区的状态 449 #[derive(Debug, Copy, Clone, Eq, PartialEq)] 450 pub enum FbState { 451 Running = 0, 452 Suspended = 1, 453 } 454 455 /// 屏幕黑屏模式。 456 #[allow(dead_code)] 457 #[derive(Debug, Copy, Clone, Eq, PartialEq)] 458 pub enum BlankMode { 459 /// 取消屏幕黑屏, 垂直同步和水平同步均打开 460 Unblank, 461 /// 屏幕黑屏, 垂直同步和水平同步均打开 462 Normal, 463 /// 屏幕黑屏, 水平同步打开, 垂直同步关闭 464 HSync, 465 /// 屏幕黑屏, 水平同步关闭, 垂直同步打开 466 VSync, 467 /// 屏幕黑屏, 水平同步和垂直同步均关闭 468 Powerdown, 469 } 470 471 /// `FillRectData` 结构体用于表示一个矩形区域并填充特定颜色。 472 /// 473 /// # 结构体字段 474 /// * `dx`: 475 /// * `dy`: 476 /// * `width`: 477 /// * `height`: 矩形的高度 478 /// * `color`: 用于填充矩形的颜色,是一个32位无符号整数 479 /// * `rop`: 光栅操作(Raster Operation),用于定义如何将颜色应用到矩形区域 480 #[derive(Debug, Copy, Clone, Eq, PartialEq)] 481 pub struct FillRectData { 482 /// 矩形左上角的x坐标(相对于屏幕) 483 pub dx: u32, 484 /// 矩形左上角的y坐标(相对于屏幕) 485 pub dy: u32, 486 /// 矩形的宽度 487 pub width: u32, 488 /// 矩形的高度 489 pub height: u32, 490 /// 用于填充矩形的颜色,是一个32位无符号整数 491 pub color: u32, 492 /// 光栅操作(Raster Operation),用于定义如何将颜色应用到矩形区域 493 pub rop: FillRectROP, 494 } 495 496 impl FillRectData { 497 #[allow(dead_code)] new(dx: u32, dy: u32, width: u32, height: u32, color: u32, rop: FillRectROP) -> Self498 pub fn new(dx: u32, dy: u32, width: u32, height: u32, color: u32, rop: FillRectROP) -> Self { 499 Self { 500 dx, 501 dy, 502 width, 503 height, 504 color, 505 rop, 506 } 507 } 508 } 509 510 /// 光栅操作(Raster Operation),用于定义如何将颜色应用到矩形区域 511 #[allow(dead_code)] 512 #[derive(Debug, Copy, Clone, Eq, PartialEq)] 513 pub enum FillRectROP { 514 /// 复制操作,即直接将指定颜色应用到矩形区域,覆盖原有颜色。 515 Copy, 516 /// 异或操作,即将指定颜色与矩形区域原有颜色进行异或操作,结果颜色应用到矩形区域。 517 Xor, 518 } 519 520 /// `CopyAreaData` 结构体用于表示一个矩形区域,并指定从哪个源位置复制数据。 521 /// 522 /// 注意,源位置必须是有意义的(即包围的矩形都必须得在屏幕内) 523 #[derive(Debug, Copy, Clone, Eq, PartialEq)] 524 pub struct CopyAreaData { 525 /// 目标矩形左上角的x坐标 526 pub dx: i32, 527 /// 目标矩形左上角的y坐标 528 pub dy: i32, 529 /// 矩形的宽度 530 pub width: u32, 531 /// 矩形的高度 532 pub height: u32, 533 /// 源矩形左上角的x坐标 534 pub sx: i32, 535 /// 源矩形左上角的y坐标 536 pub sy: i32, 537 } 538 539 impl CopyAreaData { 540 #[allow(dead_code)] new(dx: i32, dy: i32, width: u32, height: u32, sx: i32, sy: i32) -> Self541 pub fn new(dx: i32, dy: i32, width: u32, height: u32, sx: i32, sy: i32) -> Self { 542 Self { 543 dx, 544 dy, 545 width, 546 height, 547 sx, 548 sy, 549 } 550 } 551 } 552 553 /// `FbVarScreenInfo` 结构体用于描述屏幕的各种属性。 554 #[derive(Debug, Copy, Clone, Eq, PartialEq)] 555 pub struct FbVarScreenInfo { 556 /// 可见分辨率的宽度 557 pub xres: u32, 558 /// 可见分辨率的高度 559 pub yres: u32, 560 /// 虚拟分辨率的宽度 561 pub xres_virtual: u32, 562 /// 虚拟分辨率的高度 563 pub yres_virtual: u32, 564 /// 从虚拟到可见分辨率的偏移量(宽度方向) 565 pub xoffset: u32, 566 /// 从虚拟到可见分辨率的偏移量(高度方向) 567 pub yoffset: u32, 568 /// 每像素的位数 569 pub bits_per_pixel: u32, 570 /// 颜色模式 571 pub color_mode: FbColorMode, 572 /// 红色位域 573 pub red: FbBitfield, 574 /// 绿色位域 575 pub green: FbBitfield, 576 /// 蓝色位域 577 pub blue: FbBitfield, 578 /// 透明度位域 579 pub transp: FbBitfield, 580 /// 像素格式 581 pub pixel_format: FbPixelFormat, 582 /// 激活标志(参见FB_ACTIVATE_*) 583 pub activate: FbActivateFlags, 584 /// 帧缓冲区的高度(像素) None表示未知 585 pub height: Option<u32>, 586 /// 帧缓冲区的宽度(像素) None表示未知 587 pub width: Option<u32>, 588 /// 像素时钟(皮秒) 589 pub pixclock: u32, 590 /// 左边距 591 pub left_margin: u32, 592 /// 右边距 593 pub right_margin: u32, 594 /// 上边距 595 pub upper_margin: u32, 596 /// 下边距 597 pub lower_margin: u32, 598 /// 水平同步的长度 599 pub hsync_len: u32, 600 /// 垂直同步的长度 601 pub vsync_len: u32, 602 /// 同步标志(参见FB_SYNC_*) 603 pub sync: FbSyncFlags, 604 /// 视频模式(参见FB_VMODE_*) 605 pub vmode: FbVModeFlags, 606 /// 逆时针旋转的角度 607 pub rotate_angle: u32, 608 /// 颜色空间 609 pub colorspace: V4l2Colorspace, 610 } 611 612 impl Default for FbVarScreenInfo { default() -> Self613 fn default() -> Self { 614 Self { 615 xres: Default::default(), 616 yres: Default::default(), 617 xres_virtual: Default::default(), 618 yres_virtual: Default::default(), 619 xoffset: Default::default(), 620 yoffset: Default::default(), 621 bits_per_pixel: Default::default(), 622 color_mode: Default::default(), 623 red: Default::default(), 624 green: Default::default(), 625 blue: Default::default(), 626 transp: Default::default(), 627 pixel_format: Default::default(), 628 activate: Default::default(), 629 height: None, 630 width: None, 631 pixclock: Default::default(), 632 left_margin: Default::default(), 633 right_margin: Default::default(), 634 upper_margin: Default::default(), 635 lower_margin: Default::default(), 636 hsync_len: Default::default(), 637 vsync_len: Default::default(), 638 sync: FbSyncFlags::empty(), 639 vmode: FbVModeFlags::empty(), 640 rotate_angle: Default::default(), 641 colorspace: Default::default(), 642 } 643 } 644 } 645 646 /// 帧缓冲区的颜色模式 647 /// 648 /// 默认为彩色 649 #[allow(dead_code)] 650 #[derive(Debug, Copy, Clone, Eq, PartialEq, Default)] 651 pub enum FbColorMode { 652 /// 灰度 653 GrayScale, 654 /// 彩色 655 #[default] 656 Color, 657 /// FOURCC 658 FourCC, 659 } 660 661 /// `FbBitfield` 结构体用于描述颜色字段的位域。 662 /// 663 /// 所有的偏移量都是从右边开始,位于一个精确为'bits_per_pixel'宽度的"像素"值内。 664 /// 一个像素之后是一个位流,并且未经修改地写入视频内存。 665 /// 666 /// 对于伪颜色:所有颜色组件的偏移和长度应该相同。 667 /// 偏移指定了调色板索引在像素值中的最低有效位的位置。 668 /// 长度表示可用的调色板条目的数量(即条目数 = 1 << 长度)。 669 #[derive(Debug, Copy, Clone, Eq, PartialEq, Default)] 670 pub struct FbBitfield { 671 /// 位域的起始位置 672 pub offset: u32, 673 /// 位域的长度 674 pub length: u32, 675 /// 最高有效位是否在右边 676 pub msb_right: bool, 677 } 678 679 impl FbBitfield { 680 #[allow(dead_code)] new(offset: u32, length: u32, msb_right: bool) -> Self681 pub fn new(offset: u32, length: u32, msb_right: bool) -> Self { 682 Self { 683 offset, 684 length, 685 msb_right, 686 } 687 } 688 } 689 690 bitflags! { 691 /// `FbActivateFlags` 用于描述帧缓冲区的激活标志。 692 /// 693 /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/include/uapi/linux/fb.h#198 694 pub struct FbActivateFlags: u32 { 695 /// 立即设置值(或vbl) 696 const FB_ACTIVATE_NOW = 0; 697 /// 在下一次打开时激活 698 const FB_ACTIVATE_NXTOPEN = 1; 699 /// don't set, round up impossible values 700 const FB_ACTIVATE_TEST = 2; 701 const FB_ACTIVATE_MASK = 15; 702 703 /// 在下一个vbl上激活值 704 const FB_ACTIVATE_VBL = 16; 705 /// 在vbl上更改色彩映射 706 const FB_ACTIVATE_CHANGE_CMAP_VBL = 32; 707 /// 更改此fb上的所有VC 708 const FB_ACTIVATE_ALL = 64; 709 /// 即使没有变化也强制应用 710 const FB_ACTIVATE_FORCE = 128; 711 /// 使视频模式无效 712 const FB_ACTIVATE_INV_MODE = 256; 713 /// 用于KDSET vt ioctl 714 const FB_ACTIVATE_KD_TEXT = 512; 715 } 716 } 717 718 impl Default for FbActivateFlags { default() -> Self719 fn default() -> Self { 720 FbActivateFlags::FB_ACTIVATE_NOW 721 } 722 } 723 724 #[allow(dead_code)] 725 #[derive(Debug, Copy, Clone, Eq, PartialEq, Default)] 726 pub enum FbPixelFormat { 727 #[default] 728 Standard, 729 /// Hold And Modify 730 HAM, 731 /// order of pixels in each byte is reversed 732 Reserved, 733 } 734 735 bitflags! { 736 pub struct FbSyncFlags: u32 { 737 /// 水平同步高电平有效 738 const FB_SYNC_HOR_HIGH_ACT = 1; 739 /// 垂直同步高电平有效 740 const FB_SYNC_VERT_HIGH_ACT = 2; 741 /// 外部同步 742 const FB_SYNC_EXT = 4; 743 /// 复合同步高电平有效 744 const FB_SYNC_COMP_HIGH_ACT = 8; 745 /// 广播视频时序 746 const FB_SYNC_BROADCAST = 16; 747 /// sync on green 748 const FB_SYNC_ON_GREEN = 32; 749 } 750 } 751 752 bitflags! { 753 /// `FbVModeFlags` 用于描述帧缓冲区的视频模式。 754 pub struct FbVModeFlags: u32 { 755 /// 非交错 756 const FB_VMODE_NONINTERLACED = 0; 757 /// 交错 758 const FB_VMODE_INTERLACED = 1; 759 /// 双扫描 760 const FB_VMODE_DOUBLE = 2; 761 /// 交错:首先是顶行 762 const FB_VMODE_ODD_FLD_FIRST = 4; 763 /// 掩码 764 const FB_VMODE_MASK = 255; 765 /// ywrap代替平移 766 const FB_VMODE_YWRAP = 256; 767 /// 平滑xpan可能(内部使用) 768 const FB_VMODE_SMOOTH_XPAN = 512; 769 /// 不更新x/yoffset 770 const FB_VMODE_CONUPDATE = 512; 771 } 772 } 773 774 /// 视频颜色空间 775 #[allow(dead_code)] 776 #[derive(Debug, Copy, Clone, Eq, PartialEq, Default)] 777 pub enum V4l2Colorspace { 778 /// 默认颜色空间,即让驱动程序自行判断。只能用于视频捕获。 779 #[default] 780 Default = 0, 781 /// SMPTE 170M:用于广播NTSC/PAL SDTV 782 Smpte170m = 1, 783 /// 过时的1998年前的SMPTE 240M HDTV标准,已被Rec 709取代 784 Smpte240m = 2, 785 /// Rec.709:用于HDTV 786 Rec709 = 3, 787 /// 已弃用,不要使用。没有驱动程序会返回这个。这是基于对bt878数据表的误解。 788 Bt878 = 4, 789 /// NTSC 1953颜色空间。只有在处理非常非常旧的NTSC录音时才有意义。已被SMPTE 170M取代。 790 System470M = 5, 791 /// EBU Tech 3213 PAL/SECAM颜色空间。 792 System470Bg = 6, 793 /// 实际上是V4L2_COLORSPACE_SRGB,V4L2_YCBCR_ENC_601和V4L2_QUANTIZATION_FULL_RANGE的简写。用于(Motion-)JPEG。 794 Jpeg = 7, 795 /// 用于RGB颜色空间,如大多数网络摄像头所产生的。 796 Srgb = 8, 797 /// opRGB颜色空间 798 Oprgb = 9, 799 /// BT.2020颜色空间,用于UHDTV。 800 Bt2020 = 10, 801 /// Raw颜色空间:用于RAW未处理的图像 802 Raw = 11, 803 /// DCI-P3颜色空间,用于电影投影机 804 DciP3 = 12, 805 806 /// Largest supported colorspace value, assigned by the compiler, used 807 /// by the framework to check for invalid values. 808 Last, 809 } 810 811 /// `FixedScreenInfo` 结构体用于描述屏幕的固定属性。 812 #[allow(dead_code)] 813 #[derive(Debug, Copy, Clone, Eq, PartialEq)] 814 pub struct FixedScreenInfo { 815 // 字符串,用于标识屏幕,例如 "TT Builtin" 816 pub id: [char; 16], 817 // 帧缓冲区的起始物理地址 818 pub smem_start: Option<PhysAddr>, 819 // 帧缓冲区的长度 820 pub smem_len: usize, 821 // 屏幕类型,参考 FB_TYPE_ 822 pub fb_type: FbType, 823 // 用于表示交错平面的小端辅助类型 824 pub type_aux: u32, 825 // 视觉类型,参考 FB_VISUAL_ 826 pub visual: FbVisual, 827 // 水平缩放步长,如果无硬件缩放,则为0 828 pub xpanstep: u16, 829 // 垂直缩放步长,如果无硬件缩放,则为0 830 pub ypanstep: u16, 831 // 垂直环绕步长,如果无硬件环绕,则为0 832 pub ywrapstep: u16, 833 // 一行的大小(以字节为单位) 834 pub line_length: u32, 835 // 内存映射I/O端口的起始物理地址 836 pub mmio_start: Option<PhysAddr>, 837 // 内存映射I/O的长度 838 pub mmio_len: usize, 839 // 表示驱动器拥有的特定芯片/卡片类型 840 pub accel: FbAccel, 841 // 表示支持的特性,参考 FB_CAP_ 842 pub capabilities: FbCapability, 843 } 844 845 impl FixedScreenInfo { 846 /// 将字符串转换为长度为16的字符数组(包含结尾的`\0`) 847 /// 848 /// ## 参数 849 /// 850 /// - `name`: 字符串,长度不超过15,超过的部分将被截断 851 /// 852 /// ## 返回 853 /// 854 /// 长度为16的字符数组 name2id(name: &str) -> [char; 16]855 pub const fn name2id(name: &str) -> [char; 16] { 856 let mut id = [0u8 as char; 16]; 857 let mut i = 0; 858 859 while i < 15 && i < name.len() { 860 id[i] = name.as_bytes()[i] as char; 861 i += 1; 862 } 863 864 id[i] = '\0'; 865 return id; 866 } 867 } 868 869 impl Default for FixedScreenInfo { default() -> Self870 fn default() -> Self { 871 Self { 872 id: Default::default(), 873 smem_start: None, 874 smem_len: Default::default(), 875 fb_type: FbType::PackedPixels, 876 type_aux: Default::default(), 877 visual: FbVisual::Mono10, 878 xpanstep: Default::default(), 879 ypanstep: Default::default(), 880 ywrapstep: Default::default(), 881 line_length: Default::default(), 882 mmio_start: None, 883 mmio_len: Default::default(), 884 accel: Default::default(), 885 capabilities: Default::default(), 886 } 887 } 888 } 889 890 /// 帧缓冲类型 891 #[allow(dead_code)] 892 #[derive(Debug, Copy, Clone, Eq, PartialEq)] 893 pub enum FbType { 894 /// 压缩像素 895 PackedPixels = 0, 896 /// 非交错平面 897 Planes = 1, 898 /// 交错平面 899 InterleavedPlanes = 2, 900 /// 文本/属性 901 Text = 3, 902 /// EGA/VGA平面 903 VgaPlanes = 4, 904 /// 由V4L2 FOURCC标识的类型 905 FourCC = 5, 906 } 907 908 /// 帧缓冲视觉类型 909 #[allow(dead_code)] 910 #[derive(Debug, Copy, Clone, Eq, PartialEq)] 911 pub enum FbVisual { 912 /// 单色。1=黑色 0=白色 913 Mono01 = 0, 914 /// 单色。1=白色 0=黑色 915 Mono10 = 1, 916 /// 真彩色 917 TrueColor = 2, 918 /// 伪彩色(如Atari) 919 PseudoColor = 3, 920 /// 直接颜色 921 DirectColor = 4, 922 /// 只读的伪彩色 923 StaticPseudoColor = 5, 924 /// 由FOURCC标识的类型 925 FourCC, 926 } 927 928 #[allow(dead_code)] 929 #[derive(Debug, Copy, Clone, Eq, PartialEq, Default)] 930 pub enum FbCapability { 931 #[default] 932 Default = 0, 933 /// 设备支持基于FOURCC的格式。 934 FourCC, 935 } 936 937 /// 视频模式 938 #[allow(dead_code)] 939 #[derive(Debug, Clone, Eq, PartialEq)] 940 pub struct FbVideoMode { 941 /// 可选的名称 942 pub name: Option<String>, 943 /// 可选的刷新率 944 pub refresh: Option<u32>, 945 /// 水平分辨率 946 pub xres: u32, 947 /// 垂直分辨率 948 pub yres: u32, 949 /// 像素时钟 950 pub pixclock: u32, 951 /// 左边距 952 pub left_margin: u32, 953 /// 右边距 954 pub right_margin: u32, 955 /// 上边距 956 pub upper_margin: u32, 957 /// 下边距 958 pub lower_margin: u32, 959 /// 水平同步长度 960 pub hsync_len: u32, 961 /// 垂直同步长度 962 pub vsync_len: u32, 963 /// 同步 964 pub sync: FbSyncFlags, 965 /// 视频模式 966 pub vmode: FbVModeFlags, 967 /// 标志 968 pub flag: u32, 969 } 970 971 #[allow(dead_code)] 972 #[derive(Debug, Copy, Clone, Eq, PartialEq, Default)] 973 pub enum FbAccel { 974 /// 没有硬件加速器 975 #[default] 976 None, 977 978 AtariBlitter = 1, 979 AmigaBlitter = 2, 980 S3Trio64 = 3, 981 NCR77C32BLT = 4, 982 S3Virge = 5, 983 AtiMach64GX = 6, 984 DECTGA = 7, 985 AtiMach64CT = 8, 986 AtiMach64VT = 9, 987 AtiMach64GT = 10, 988 SunCreator = 11, 989 SunCGSix = 12, 990 SunLeo = 13, 991 IMSTwinTurbo = 14, 992 Acc3DLabsPermedia2 = 15, 993 MatroxMGA2064W = 16, 994 MatroxMGA1064SG = 17, 995 MatroxMGA2164W = 18, 996 MatroxMGA2164WAGP = 19, 997 MatroxMGAG400 = 20, 998 NV3 = 21, 999 NV4 = 22, 1000 NV5 = 23, 1001 NV6 = 24, 1002 XGIVolariV = 25, 1003 XGIVolariZ = 26, 1004 Omap1610 = 27, 1005 TridentTGUI = 28, 1006 Trident3DImage = 29, 1007 TridentBlade3D = 30, 1008 TridentBladeXP = 31, 1009 CirrusAlpine = 32, 1010 NeoMagicNM2070 = 90, 1011 NeoMagicNM2090 = 91, 1012 NeoMagicNM2093 = 92, 1013 NeoMagicNM2097 = 93, 1014 NeoMagicNM2160 = 94, 1015 NeoMagicNM2200 = 95, 1016 NeoMagicNM2230 = 96, 1017 NeoMagicNM2360 = 97, 1018 NeoMagicNM2380 = 98, 1019 PXA3XX = 99, 1020 1021 Savage4 = 0x80, 1022 Savage3D = 0x81, 1023 Savage3DMV = 0x82, 1024 Savage2000 = 0x83, 1025 SavageMXMV = 0x84, 1026 SavageMX = 0x85, 1027 SavageIXMV = 0x86, 1028 SavageIX = 0x87, 1029 ProSavagePM = 0x88, 1030 ProSavageKM = 0x89, 1031 S3Twister = 0x8a, 1032 S3TwisterK = 0x8b, 1033 SuperSavage = 0x8c, 1034 ProSavageDDR = 0x8d, 1035 ProSavageDDRK = 0x8e, 1036 // Add other accelerators here 1037 } 1038 1039 #[allow(dead_code)] 1040 #[derive(Debug, Copy, Clone)] 1041 pub struct BootTimeScreenInfo { 1042 pub origin_x: u8, 1043 pub origin_y: u8, 1044 /// text mode时,每行的字符数 1045 pub origin_video_cols: u8, 1046 /// text mode时,行数 1047 pub origin_video_lines: u8, 1048 /// 标记屏幕是否为VGA类型 1049 pub is_vga: bool, 1050 /// video mode type 1051 pub video_type: BootTimeVideoType, 1052 1053 // 以下字段用于线性帧缓冲区 1054 /// 线性帧缓冲区的起始物理地址 1055 pub lfb_base: PhysAddr, 1056 /// 线性帧缓冲区在初始化阶段被映射到的起始虚拟地址 1057 /// 1058 /// 这个值可能会被设置2次: 1059 /// 1060 /// - 内存管理初始化之前,early init阶段,临时映射 1061 /// - 内存管理初始化完毕,重新映射时被设置 1062 pub lfb_virt_base: Option<VirtAddr>, 1063 /// 线性帧缓冲区的长度 1064 pub lfb_size: usize, 1065 /// 线性帧缓冲区的宽度(像素) 1066 pub lfb_width: u32, 1067 /// 线性帧缓冲区的高度(像素) 1068 pub lfb_height: u32, 1069 /// 线性帧缓冲区的深度(位数) 1070 pub lfb_depth: u8, 1071 /// 红色位域的大小 1072 pub red_size: u8, 1073 /// 红色位域的偏移量(左移位数) 1074 pub red_pos: u8, 1075 /// 绿色位域的大小 1076 pub green_size: u8, 1077 /// 绿色位域的偏移量(左移位数) 1078 pub green_pos: u8, 1079 /// 蓝色位域的大小 1080 pub blue_size: u8, 1081 /// 蓝色位域的偏移量(左移位数) 1082 pub blue_pos: u8, 1083 } 1084 1085 impl BootTimeScreenInfo { 1086 pub const DEFAULT: Self = Self { 1087 origin_x: 0, 1088 origin_y: 0, 1089 is_vga: false, 1090 lfb_base: PhysAddr::new(0), 1091 lfb_size: 0, 1092 lfb_width: 0, 1093 lfb_height: 0, 1094 red_size: 0, 1095 red_pos: 0, 1096 green_size: 0, 1097 green_pos: 0, 1098 blue_size: 0, 1099 blue_pos: 0, 1100 video_type: BootTimeVideoType::UnDefined, 1101 origin_video_cols: 0, 1102 origin_video_lines: 0, 1103 lfb_virt_base: None, 1104 lfb_depth: 0, 1105 }; 1106 } 1107 1108 /// Video types for different display hardware 1109 #[allow(dead_code)] 1110 #[derive(Debug, Copy, Clone, Eq, PartialEq)] 1111 pub enum BootTimeVideoType { 1112 UnDefined, 1113 /// Monochrome Text Display 1114 Mda, 1115 /// CGA Display 1116 Cga, 1117 /// EGA/VGA in Monochrome Mode 1118 EgaM, 1119 /// EGA in Color Mode 1120 EgaC, 1121 /// VGA+ in Color Mode 1122 VgaC, 1123 /// VESA VGA in graphic mode 1124 Vlfb, 1125 /// ACER PICA-61 local S3 video 1126 PicaS3, 1127 /// MIPS Magnum 4000 G364 video 1128 MipsG364, 1129 /// Various SGI graphics hardware 1130 Sgi, 1131 /// DEC TGA 1132 TgaC, 1133 /// Sun frame buffer 1134 Sun, 1135 /// Sun PCI based frame buffer 1136 SunPci, 1137 /// PowerMacintosh frame buffer 1138 Pmac, 1139 /// EFI graphic mode 1140 Efi, 1141 } 1142 1143 impl From<u8> for BootTimeVideoType { from(value: u8) -> Self1144 fn from(value: u8) -> Self { 1145 match value { 1146 0 => BootTimeVideoType::UnDefined, 1147 0x10 => BootTimeVideoType::Mda, 1148 0x11 => BootTimeVideoType::Cga, 1149 0x20 => BootTimeVideoType::EgaM, 1150 0x21 => BootTimeVideoType::EgaC, 1151 0x22 => BootTimeVideoType::VgaC, 1152 0x23 => BootTimeVideoType::Vlfb, 1153 0x30 => BootTimeVideoType::PicaS3, 1154 0x31 => BootTimeVideoType::MipsG364, 1155 0x33 => BootTimeVideoType::Sgi, 1156 0x40 => BootTimeVideoType::TgaC, 1157 0x50 => BootTimeVideoType::Sun, 1158 0x51 => BootTimeVideoType::SunPci, 1159 0x60 => BootTimeVideoType::Pmac, 1160 0x70 => BootTimeVideoType::Efi, 1161 1162 _ => BootTimeVideoType::UnDefined, 1163 } 1164 } 1165 } 1166 1167 #[derive(Debug, Default)] 1168 pub struct FbCursor { 1169 /// 设置选项 1170 pub set_mode: FbCursorSetMode, 1171 /// 开关选项 1172 pub enable: bool, 1173 /// 表示光标图像的位操作,true表示XOR,false表示COPY 1174 pub rop: bool, 1175 /// 表示光标掩码(mask)的数据。掩码用于定义光标的形状,指定了哪些像素是光标的一部分。 1176 pub mask: Vec<u8>, 1177 1178 /// 表示光标的热点位置,即在光标图像中被认为是"焦点"的位置 1179 pub hot_x: u32, 1180 pub hot_y: u32, 1181 1182 /// 光标图像 1183 pub image: FbImage, 1184 } 1185 1186 bitflags! { 1187 /// 硬件光标控制 1188 #[derive(Default)] 1189 pub struct FbCursorSetMode:u8 { 1190 /// 设置位图 1191 const FB_CUR_SETIMAGE = 0x01; 1192 /// 设置位置 1193 const FB_CUR_SETPOS = 0x02; 1194 /// 设置热点 1195 const FB_CUR_SETHOT = 0x04; 1196 /// ColorMap 1197 const FB_CUR_SETCMAP = 0x08; 1198 /// 形状 1199 const FB_CUR_SETSHAPE = 0x10; 1200 /// Size 1201 const FB_CUR_SETSIZE = 0x20; 1202 /// 全设置 1203 const FB_CUR_SETALL = 0xFF; 1204 } 1205 } 1206 1207 #[allow(dead_code)] 1208 #[derive(Debug, Clone, Copy)] 1209 pub enum ScrollMode { 1210 Move, 1211 PanMove, 1212 WrapMove, 1213 Redraw, 1214 PanRedraw, 1215 } 1216 1217 impl Default for ScrollMode { 1218 /// ## 默认Move default() -> Self1219 fn default() -> Self { 1220 Self::Move 1221 } 1222 } 1223 1224 #[derive(Debug, Default, Clone)] 1225 pub struct FbImage { 1226 pub x: u32, 1227 pub y: u32, 1228 pub width: u32, 1229 pub height: u32, 1230 pub fg: u32, 1231 pub bg: u32, 1232 pub depth: u8, 1233 pub data: Vec<u8>, 1234 } 1235