1 use core::{ 2 fmt::Debug, 3 intrinsics::unlikely, 4 sync::atomic::{AtomicBool, AtomicU32, Ordering}, 5 }; 6 7 use alloc::{boxed::Box, collections::LinkedList, string::String, sync::Arc}; 8 use system_error::SystemError; 9 10 use crate::{ 11 driver::{ 12 tty::serial::serial8250::send_to_default_serial8250_port, video::video_refresh_manager, 13 }, 14 libs::{lib_ui::textui::textui_is_enable_put_to_window, rwlock::RwLock, spinlock::SpinLock}, 15 mm::VirtAddr, 16 }; 17 18 use super::{ 19 textui::{textui_disable_put_to_window, textui_enable_put_to_window}, 20 textui_no_alloc::textui_init_no_alloc, 21 }; 22 23 /// 全局的UI框架列表 24 pub static SCM_FRAMEWORK_LIST: SpinLock<LinkedList<Arc<dyn ScmUiFramework>>> = 25 SpinLock::new(LinkedList::new()); 26 27 /// 当前在使用的UI框架 28 pub static CURRENT_FRAMEWORK: RwLock<Option<Arc<dyn ScmUiFramework>>> = RwLock::new(None); 29 30 /// 是否启用双缓冲 31 pub static SCM_DOUBLE_BUFFER_ENABLED: AtomicBool = AtomicBool::new(false); 32 33 bitflags! { 34 pub struct ScmBufferFlag:u8 { 35 // 帧缓冲区标志位 36 const SCM_BF_FB = 1 << 0; // 当前buffer是设备显存中的帧缓冲区 37 const SCM_BF_DB = 1 << 1; // 当前buffer是双缓冲 38 const SCM_BF_TEXT = 1 << 2; // 使用文本模式 39 const SCM_BF_PIXEL = 1 << 3; // 使用图像模式 40 } 41 } 42 #[derive(Clone, Debug)] 43 #[allow(dead_code)] 44 pub enum ScmFramworkType { 45 Text, 46 Gui, 47 Unused, 48 } 49 #[derive(Debug, Clone)] 50 pub enum ScmBuffer { 51 DeviceBuffer(VirtAddr), 52 DoubleBuffer(Arc<SpinLock<Box<[u32]>>>), 53 } 54 55 #[derive(Debug, Clone)] 56 pub struct ScmBufferInfo { 57 width: u32, // 帧缓冲区宽度(pixel或columns) 58 height: u32, // 帧缓冲区高度(pixel或lines) 59 size: u32, // 帧缓冲区大小(bytes) 60 bit_depth: u32, // 像素点位深度 61 pub buf: ScmBuffer, 62 flags: ScmBufferFlag, // 帧缓冲区标志位 63 } 64 65 #[allow(dead_code)] 66 impl ScmBufferInfo { 67 /// 创建新的帧缓冲区信息 68 /// 69 /// ## 参数 70 /// 71 /// - `buf_type` 帧缓冲区类型 72 /// 73 /// ## 返回值 74 /// 75 /// - `Result<Self, SystemError>` 创建成功返回新的帧缓冲区结构体,创建失败返回错误码 76 pub fn new(mut buf_type: ScmBufferFlag) -> Result<Self, SystemError> { 77 if unlikely(SCM_DOUBLE_BUFFER_ENABLED.load(Ordering::SeqCst) == false) { 78 let mut device_buffer = video_refresh_manager().device_buffer().clone(); 79 buf_type.remove(ScmBufferFlag::SCM_BF_DB); 80 buf_type.insert(ScmBufferFlag::SCM_BF_FB); 81 device_buffer.flags = buf_type; 82 return Ok(device_buffer); 83 } else { 84 let device_buffer_guard = video_refresh_manager().device_buffer(); 85 86 let buf_space: Arc<SpinLock<Box<[u32]>>> = Arc::new(SpinLock::new( 87 vec![0u32; (device_buffer_guard.size / 4) as usize].into_boxed_slice(), 88 )); 89 90 assert!(buf_type.contains(ScmBufferFlag::SCM_BF_DB)); 91 92 assert_eq!( 93 device_buffer_guard.size as usize, 94 buf_space.lock().len() * core::mem::size_of::<u32>() 95 ); 96 97 // 创建双缓冲区 98 let buffer = Self { 99 width: device_buffer_guard.width, 100 height: device_buffer_guard.height, 101 size: device_buffer_guard.size, 102 bit_depth: device_buffer_guard.bit_depth, 103 flags: buf_type, 104 buf: ScmBuffer::DoubleBuffer(buf_space), 105 }; 106 drop(device_buffer_guard); 107 108 return Ok(buffer); 109 } 110 } 111 112 pub unsafe fn new_device_buffer( 113 width: u32, 114 height: u32, 115 size: u32, 116 bit_depth: u32, 117 buf_type: ScmBufferFlag, 118 vaddr: VirtAddr, 119 ) -> Result<Self, SystemError> { 120 let buffer = Self { 121 width, 122 height, 123 size, 124 bit_depth, 125 flags: buf_type, 126 buf: ScmBuffer::DeviceBuffer(vaddr), 127 }; 128 return Ok(buffer); 129 } 130 131 pub fn buf_size(&self) -> usize { 132 self.size as usize 133 } 134 135 pub fn bit_depth(&self) -> u32 { 136 self.bit_depth 137 } 138 139 pub fn height(&self) -> u32 { 140 self.height 141 } 142 143 pub fn width(&self) -> u32 { 144 self.width 145 } 146 147 pub fn is_double_buffer(&self) -> bool { 148 match &self.buf { 149 ScmBuffer::DoubleBuffer(_) => true, 150 _ => false, 151 } 152 } 153 pub fn is_device_buffer(&self) -> bool { 154 match &self.buf { 155 ScmBuffer::DeviceBuffer(_) => true, 156 _ => false, 157 } 158 } 159 160 pub fn copy_from_nonoverlapping(&mut self, src: &ScmBufferInfo) { 161 assert!(self.buf_size() == src.buf_size()); 162 match &self.buf { 163 ScmBuffer::DeviceBuffer(vaddr) => { 164 let len = self.buf_size() / core::mem::size_of::<u32>(); 165 let self_buf_guard = 166 unsafe { core::slice::from_raw_parts_mut(vaddr.data() as *mut u32, len) }; 167 match &src.buf { 168 ScmBuffer::DeviceBuffer(vaddr) => { 169 let src_buf_guard = 170 unsafe { core::slice::from_raw_parts(vaddr.data() as *const u32, len) }; 171 self_buf_guard.copy_from_slice(src_buf_guard); 172 } 173 ScmBuffer::DoubleBuffer(double_buffer) => { 174 let src_buf_guard = double_buffer.lock(); 175 self_buf_guard.copy_from_slice(src_buf_guard.as_ref()); 176 } 177 }; 178 } 179 180 ScmBuffer::DoubleBuffer(double_buffer) => { 181 let mut double_buffer_guard = double_buffer.lock(); 182 match &src.buf { 183 ScmBuffer::DeviceBuffer(vaddr) => { 184 let len = src.buf_size() / core::mem::size_of::<u32>(); 185 double_buffer_guard.as_mut().copy_from_slice(unsafe { 186 core::slice::from_raw_parts(vaddr.data() as *const u32, len) 187 }); 188 } 189 ScmBuffer::DoubleBuffer(double_buffer) => { 190 let x = double_buffer.lock(); 191 double_buffer_guard.as_mut().copy_from_slice(x.as_ref()); 192 } 193 }; 194 } 195 } 196 } 197 } 198 199 #[derive(Debug, Copy, Clone, Eq, PartialEq, PartialOrd, Ord, Hash)] 200 pub struct ScmUiFrameworkId(u32); 201 202 impl ScmUiFrameworkId { 203 /// 分配一个新的框架id 204 pub fn new() -> Self { 205 static MAX_ID: AtomicU32 = AtomicU32::new(0); 206 return ScmUiFrameworkId(MAX_ID.fetch_add(1, Ordering::SeqCst)); 207 } 208 } 209 #[allow(dead_code)] 210 #[derive(Debug, Clone)] 211 pub struct ScmUiFrameworkMetadata { 212 id: ScmUiFrameworkId, 213 name: String, 214 framework_type: ScmFramworkType, 215 pub buf_info: ScmBufferInfo, 216 } 217 218 impl ScmUiFrameworkMetadata { 219 pub fn new(name: String, framework_type: ScmFramworkType) -> Self { 220 match framework_type { 221 ScmFramworkType::Text => { 222 let result = ScmUiFrameworkMetadata { 223 id: ScmUiFrameworkId::new(), 224 name, 225 framework_type: ScmFramworkType::Text, 226 buf_info: ScmBufferInfo::new( 227 ScmBufferFlag::SCM_BF_TEXT | ScmBufferFlag::SCM_BF_DB, 228 ) 229 .unwrap(), 230 }; 231 232 return result; 233 } 234 ScmFramworkType::Gui => todo!(), 235 ScmFramworkType::Unused => todo!(), 236 } 237 } 238 pub fn buf_info(&self) -> ScmBufferInfo { 239 return self.buf_info.clone(); 240 } 241 pub fn set_buf_info(&mut self, buf_info: ScmBufferInfo) { 242 self.buf_info = buf_info; 243 } 244 } 245 pub trait ScmUiFramework: Sync + Send + Debug { 246 // 安装ui框架的回调函数 247 fn install(&self) -> Result<i32, SystemError> { 248 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 249 } 250 // 卸载ui框架的回调函数 251 fn uninstall(&self) -> Result<i32, SystemError> { 252 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 253 } 254 // 启用ui框架的回调函数 255 fn enable(&self) -> Result<i32, SystemError> { 256 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 257 } 258 // 禁用ui框架的回调函数 259 fn disable(&self) -> Result<i32, SystemError> { 260 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 261 } 262 // 改变ui框架的帧缓冲区的回调函数 263 fn change(&self, _buf: ScmBufferInfo) -> Result<i32, SystemError> { 264 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 265 } 266 /// @brief 获取ScmUiFramework的元数据 267 /// @return 成功:Ok(ScmUiFramework的元数据) 268 /// 失败:Err(错误码) 269 fn metadata(&self) -> Result<ScmUiFrameworkMetadata, SystemError> { 270 // 若文件系统没有实现此方法,则返回“不支持” 271 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 272 } 273 } 274 275 /// 初始化屏幕控制模块 276 /// 277 /// ## 调用时机 278 /// 279 /// 该函数在内核启动的早期进行调用。调用时,内存管理模块尚未初始化。 280 pub fn scm_init(enable_put_to_window: bool) { 281 SCM_DOUBLE_BUFFER_ENABLED.store(false, Ordering::SeqCst); // 禁用双缓冲 282 if enable_put_to_window { 283 textui_enable_put_to_window(); 284 } else { 285 textui_disable_put_to_window(); 286 } 287 textui_init_no_alloc(enable_put_to_window); 288 289 send_to_default_serial8250_port("\nfinish_scm_init\n\0".as_bytes()); 290 } 291 292 /// 启用某个ui框架,将它的帧缓冲区渲染到屏幕上 293 /// ## 参数 294 /// 295 /// - framework 要启动的ui框架 296 297 pub fn scm_framework_enable(framework: Arc<dyn ScmUiFramework>) -> Result<i32, SystemError> { 298 // 获取信息 299 let metadata = framework.metadata()?; 300 301 // if metadata.buf_info.buf.is_null() { 302 // return Err(SystemError::EINVAL); 303 // } 304 let mut current_framework = CURRENT_FRAMEWORK.write(); 305 306 if SCM_DOUBLE_BUFFER_ENABLED.load(Ordering::SeqCst) == true { 307 video_refresh_manager().set_refresh_target(&metadata.buf_info)?; 308 } 309 310 framework.enable()?; 311 current_framework.replace(framework); 312 313 return Ok(0); 314 } 315 /// 向屏幕管理器注册UI框架 316 /// 317 /// ## 参数 318 /// - framework 框架结构体 319 320 pub fn scm_register(framework: Arc<dyn ScmUiFramework>) -> Result<i32, SystemError> { 321 // 把ui框架加入链表 322 323 SCM_FRAMEWORK_LIST.lock().push_back(framework.clone()); 324 // 调用ui框架的回调函数以安装ui框架,并将其激活 325 framework.install()?; 326 327 // 如果当前还没有框架获得了屏幕的控制权,就让其拿去 328 if CURRENT_FRAMEWORK.read().is_none() { 329 return scm_framework_enable(framework); 330 } 331 return Ok(0); 332 } 333 334 /// 屏幕管理器启用双缓冲区 335 #[allow(dead_code)] 336 pub fn scm_enable_double_buffer() -> Result<i32, SystemError> { 337 if SCM_DOUBLE_BUFFER_ENABLED.load(Ordering::SeqCst) { 338 // 已经开启了双缓冲区了, 直接退出 339 return Ok(0); 340 } 341 let scm_list = SCM_FRAMEWORK_LIST.lock(); 342 if scm_list.is_empty() { 343 // scm 框架链表为空 344 return Ok(0); 345 } 346 drop(scm_list); 347 SCM_DOUBLE_BUFFER_ENABLED.store(true, Ordering::SeqCst); 348 // 创建双缓冲区 349 let buf_info = ScmBufferInfo::new(ScmBufferFlag::SCM_BF_DB | ScmBufferFlag::SCM_BF_PIXEL)?; 350 351 // 设置定时刷新的对象 352 video_refresh_manager() 353 .set_refresh_target(&buf_info) 354 .expect("set refresh target failed"); 355 356 // 设置当前框架的帧缓冲区 357 CURRENT_FRAMEWORK 358 .write() 359 .as_ref() 360 .unwrap() 361 .change(buf_info)?; 362 // 遍历当前所有使用帧缓冲区的框架,更新为双缓冲区 363 for framework in SCM_FRAMEWORK_LIST.lock().iter_mut() { 364 if !(*framework).metadata()?.buf_info.is_double_buffer() { 365 let new_buf_info = 366 ScmBufferInfo::new(ScmBufferFlag::SCM_BF_DB | ScmBufferFlag::SCM_BF_PIXEL)?; 367 (*framework).change(new_buf_info)?; 368 } 369 } 370 // 通知显示驱动,启动双缓冲 371 video_refresh_manager().video_reinitialize(true)?; 372 373 return Ok(0); 374 } 375 376 /// 允许往窗口打印信息 377 pub fn scm_enable_put_to_window() { 378 // mm之前要继续往窗口打印信息时,因为没有动态内存分配(textui并没有往scm注册),且使用的是textui,要直接修改textui里面的值 379 if CURRENT_FRAMEWORK.read().is_none() { 380 textui_enable_put_to_window(); 381 } else { 382 let r = CURRENT_FRAMEWORK 383 .write() 384 .as_ref() 385 .unwrap() 386 .enable() 387 .unwrap_or_else(|e| e.to_posix_errno()); 388 if r.is_negative() { 389 send_to_default_serial8250_port("scm_enable_put_to_window() failed.\n\0".as_bytes()); 390 } 391 } 392 } 393 /// 禁止往窗口打印信息 394 pub fn scm_disable_put_to_window() { 395 // mm之前要停止往窗口打印信息时,因为没有动态内存分配(rwlock与otion依然能用,但是textui并没有往scm注册),且使用的是textui,要直接修改textui里面的值 396 if CURRENT_FRAMEWORK.read().is_none() { 397 textui_disable_put_to_window(); 398 assert!(textui_is_enable_put_to_window() == false); 399 } else { 400 let r = CURRENT_FRAMEWORK 401 .write() 402 .as_ref() 403 .unwrap() 404 .disable() 405 .unwrap_or_else(|e| e.to_posix_errno()); 406 if r.is_negative() { 407 send_to_default_serial8250_port("scm_disable_put_to_window() failed.\n\0".as_bytes()); 408 } 409 } 410 } 411 /// 当内存管理单元被初始化之后,重新处理帧缓冲区问题 412 #[no_mangle] 413 pub extern "C" fn scm_reinit() -> i32 { 414 let r = true_scm_reinit().unwrap_or_else(|e| e.to_posix_errno()); 415 if r.is_negative() { 416 send_to_default_serial8250_port("scm reinit failed.\n\0".as_bytes()); 417 } 418 return r; 419 } 420 fn true_scm_reinit() -> Result<i32, SystemError> { 421 video_refresh_manager() 422 .video_reinitialize(false) 423 .expect("video reinitialize failed"); 424 425 // 遍历当前所有使用帧缓冲区的框架,更新地址 426 let device_buffer = video_refresh_manager().device_buffer().clone(); 427 for framework in SCM_FRAMEWORK_LIST.lock().iter_mut() { 428 if framework.metadata()?.buf_info().is_device_buffer() { 429 framework.change(device_buffer.clone())?; 430 } 431 } 432 433 scm_enable_put_to_window(); 434 435 return Ok(0); 436 } 437