1abe3a6eaShanjiezhou use core::{ 2abe3a6eaShanjiezhou fmt::Debug, 3abe3a6eaShanjiezhou intrinsics::unlikely, 4abe3a6eaShanjiezhou sync::atomic::{AtomicBool, AtomicU32, Ordering}, 5abe3a6eaShanjiezhou }; 6abe3a6eaShanjiezhou 7abe3a6eaShanjiezhou use alloc::{boxed::Box, collections::LinkedList, string::String, sync::Arc}; 891e9d4abSLoGin use system_error::SystemError; 9abe3a6eaShanjiezhou 10abe3a6eaShanjiezhou use crate::{ 1152da9a59SGnoCiYeH driver::{serial::serial8250::send_to_default_serial8250_port, video::video_refresh_manager}, 121a72a751SLoGin libs::{lib_ui::textui::textui_is_enable_put_to_window, rwlock::RwLock, spinlock::SpinLock}, 13*2b7818e8SLoGin mm::{mmio_buddy::MMIOSpaceGuard, VirtAddr}, 14abe3a6eaShanjiezhou }; 15abe3a6eaShanjiezhou 161a72a751SLoGin use super::{ 171a72a751SLoGin textui::{textui_disable_put_to_window, textui_enable_put_to_window}, 181a72a751SLoGin textui_no_alloc::textui_init_no_alloc, 191a72a751SLoGin }; 20abe3a6eaShanjiezhou 21abe3a6eaShanjiezhou /// 全局的UI框架列表 221496ba7bSLoGin pub static SCM_FRAMEWORK_LIST: SpinLock<LinkedList<Arc<dyn ScmUiFramework>>> = 23abe3a6eaShanjiezhou SpinLock::new(LinkedList::new()); 24abe3a6eaShanjiezhou 251496ba7bSLoGin /// 当前在使用的UI框架 261496ba7bSLoGin pub static CURRENT_FRAMEWORK: RwLock<Option<Arc<dyn ScmUiFramework>>> = RwLock::new(None); 27abe3a6eaShanjiezhou 28abe3a6eaShanjiezhou /// 是否启用双缓冲 29abe3a6eaShanjiezhou pub static SCM_DOUBLE_BUFFER_ENABLED: AtomicBool = AtomicBool::new(false); 30abe3a6eaShanjiezhou 31abe3a6eaShanjiezhou bitflags! { 32abe3a6eaShanjiezhou pub struct ScmBufferFlag:u8 { 33abe3a6eaShanjiezhou // 帧缓冲区标志位 34abe3a6eaShanjiezhou const SCM_BF_FB = 1 << 0; // 当前buffer是设备显存中的帧缓冲区 35abe3a6eaShanjiezhou const SCM_BF_DB = 1 << 1; // 当前buffer是双缓冲 36abe3a6eaShanjiezhou const SCM_BF_TEXT = 1 << 2; // 使用文本模式 37abe3a6eaShanjiezhou const SCM_BF_PIXEL = 1 << 3; // 使用图像模式 38abe3a6eaShanjiezhou } 39abe3a6eaShanjiezhou } 40abe3a6eaShanjiezhou #[derive(Clone, Debug)] 41abe3a6eaShanjiezhou #[allow(dead_code)] 42abe3a6eaShanjiezhou pub enum ScmFramworkType { 43abe3a6eaShanjiezhou Text, 44abe3a6eaShanjiezhou Gui, 45abe3a6eaShanjiezhou Unused, 46abe3a6eaShanjiezhou } 471496ba7bSLoGin #[derive(Debug, Clone)] 48abe3a6eaShanjiezhou pub enum ScmBuffer { 491496ba7bSLoGin DeviceBuffer(VirtAddr), 502755467cS曾俊 DoubleBuffer(Arc<SpinLock<Box<[u8]>>>), 51abe3a6eaShanjiezhou } 521496ba7bSLoGin 531496ba7bSLoGin #[derive(Debug, Clone)] 54abe3a6eaShanjiezhou pub struct ScmBufferInfo { 55abe3a6eaShanjiezhou width: u32, // 帧缓冲区宽度(pixel或columns) 56abe3a6eaShanjiezhou height: u32, // 帧缓冲区高度(pixel或lines) 57abe3a6eaShanjiezhou size: u32, // 帧缓冲区大小(bytes) 58abe3a6eaShanjiezhou bit_depth: u32, // 像素点位深度 59*2b7818e8SLoGin device_buffer_mmio_guard: Option<Arc<MMIOSpaceGuard>>, 60abe3a6eaShanjiezhou pub buf: ScmBuffer, 61abe3a6eaShanjiezhou flags: ScmBufferFlag, // 帧缓冲区标志位 62abe3a6eaShanjiezhou } 63abe3a6eaShanjiezhou 641496ba7bSLoGin #[allow(dead_code)] 65abe3a6eaShanjiezhou impl ScmBufferInfo { 66abe3a6eaShanjiezhou /// 创建新的帧缓冲区信息 67abe3a6eaShanjiezhou /// 68abe3a6eaShanjiezhou /// ## 参数 69abe3a6eaShanjiezhou /// 70abe3a6eaShanjiezhou /// - `buf_type` 帧缓冲区类型 71abe3a6eaShanjiezhou /// 72abe3a6eaShanjiezhou /// ## 返回值 73abe3a6eaShanjiezhou /// 74abe3a6eaShanjiezhou /// - `Result<Self, SystemError>` 创建成功返回新的帧缓冲区结构体,创建失败返回错误码 751496ba7bSLoGin pub fn new(mut buf_type: ScmBufferFlag) -> Result<Self, SystemError> { 76b5b571e0SLoGin if unlikely(!SCM_DOUBLE_BUFFER_ENABLED.load(Ordering::SeqCst)) { 771496ba7bSLoGin let mut device_buffer = video_refresh_manager().device_buffer().clone(); 781496ba7bSLoGin buf_type.remove(ScmBufferFlag::SCM_BF_DB); 791496ba7bSLoGin buf_type.insert(ScmBufferFlag::SCM_BF_FB); 801496ba7bSLoGin device_buffer.flags = buf_type; 811496ba7bSLoGin return Ok(device_buffer); 82abe3a6eaShanjiezhou } else { 831496ba7bSLoGin let device_buffer_guard = video_refresh_manager().device_buffer(); 84abe3a6eaShanjiezhou 852755467cS曾俊 let buf_space: Arc<SpinLock<Box<[u8]>>> = Arc::new(SpinLock::new( 862755467cS曾俊 vec![0u8; (device_buffer_guard.size / 4) as usize].into_boxed_slice(), 87abe3a6eaShanjiezhou )); 88abe3a6eaShanjiezhou 891496ba7bSLoGin assert!(buf_type.contains(ScmBufferFlag::SCM_BF_DB)); 90abe3a6eaShanjiezhou 911496ba7bSLoGin assert_eq!( 921496ba7bSLoGin device_buffer_guard.size as usize, 932755467cS曾俊 buf_space.lock().len() * core::mem::size_of::<u8>() 941496ba7bSLoGin ); 95abe3a6eaShanjiezhou 961496ba7bSLoGin // 创建双缓冲区 971496ba7bSLoGin let buffer = Self { 981496ba7bSLoGin width: device_buffer_guard.width, 991496ba7bSLoGin height: device_buffer_guard.height, 1001496ba7bSLoGin size: device_buffer_guard.size, 1011496ba7bSLoGin bit_depth: device_buffer_guard.bit_depth, 1021496ba7bSLoGin flags: buf_type, 1031496ba7bSLoGin buf: ScmBuffer::DoubleBuffer(buf_space), 104*2b7818e8SLoGin device_buffer_mmio_guard: None, 105abe3a6eaShanjiezhou }; 1061496ba7bSLoGin drop(device_buffer_guard); 1071496ba7bSLoGin 1081496ba7bSLoGin return Ok(buffer); 109abe3a6eaShanjiezhou } 110abe3a6eaShanjiezhou } 1111496ba7bSLoGin 112*2b7818e8SLoGin pub unsafe fn set_device_buffer_mmio_guard(&mut self, guard: Arc<MMIOSpaceGuard>) { 113*2b7818e8SLoGin self.device_buffer_mmio_guard = Some(guard); 114*2b7818e8SLoGin } 115*2b7818e8SLoGin 1161496ba7bSLoGin pub unsafe fn new_device_buffer( 1171496ba7bSLoGin width: u32, 1181496ba7bSLoGin height: u32, 1191496ba7bSLoGin size: u32, 1201496ba7bSLoGin bit_depth: u32, 1211496ba7bSLoGin buf_type: ScmBufferFlag, 1221496ba7bSLoGin vaddr: VirtAddr, 123*2b7818e8SLoGin mut device_buffer_mmio_guard: Option<MMIOSpaceGuard>, 1241496ba7bSLoGin ) -> Result<Self, SystemError> { 125*2b7818e8SLoGin let mmio_guard = device_buffer_mmio_guard.take().map(Arc::new); 1261496ba7bSLoGin let buffer = Self { 1271496ba7bSLoGin width, 1281496ba7bSLoGin height, 1291496ba7bSLoGin size, 1301496ba7bSLoGin bit_depth, 1311496ba7bSLoGin flags: buf_type, 1321496ba7bSLoGin buf: ScmBuffer::DeviceBuffer(vaddr), 133*2b7818e8SLoGin device_buffer_mmio_guard: mmio_guard, 1341496ba7bSLoGin }; 1351496ba7bSLoGin return Ok(buffer); 136abe3a6eaShanjiezhou } 1371496ba7bSLoGin 1381496ba7bSLoGin pub fn buf_size(&self) -> usize { 1391496ba7bSLoGin self.size as usize 1401496ba7bSLoGin } 1411496ba7bSLoGin 1421496ba7bSLoGin pub fn bit_depth(&self) -> u32 { 1431496ba7bSLoGin self.bit_depth 1441496ba7bSLoGin } 1451496ba7bSLoGin 1461496ba7bSLoGin pub fn height(&self) -> u32 { 147abe3a6eaShanjiezhou self.height 148abe3a6eaShanjiezhou } 1491496ba7bSLoGin 1501496ba7bSLoGin pub fn width(&self) -> u32 { 151abe3a6eaShanjiezhou self.width 152abe3a6eaShanjiezhou } 1531496ba7bSLoGin 154abe3a6eaShanjiezhou pub fn is_double_buffer(&self) -> bool { 155b5b571e0SLoGin matches!(&self.buf, ScmBuffer::DoubleBuffer(_)) 156abe3a6eaShanjiezhou } 157abe3a6eaShanjiezhou pub fn is_device_buffer(&self) -> bool { 158b5b571e0SLoGin matches!(&self.buf, ScmBuffer::DeviceBuffer(_)) 159abe3a6eaShanjiezhou } 1601496ba7bSLoGin 1611496ba7bSLoGin pub fn copy_from_nonoverlapping(&mut self, src: &ScmBufferInfo) { 1621496ba7bSLoGin assert!(self.buf_size() == src.buf_size()); 1631496ba7bSLoGin match &self.buf { 1641496ba7bSLoGin ScmBuffer::DeviceBuffer(vaddr) => { 1651496ba7bSLoGin let len = self.buf_size() / core::mem::size_of::<u32>(); 1661496ba7bSLoGin let self_buf_guard = 1672755467cS曾俊 unsafe { core::slice::from_raw_parts_mut(vaddr.data() as *mut u8, len) }; 1681496ba7bSLoGin match &src.buf { 1691496ba7bSLoGin ScmBuffer::DeviceBuffer(vaddr) => { 1701496ba7bSLoGin let src_buf_guard = 1712755467cS曾俊 unsafe { core::slice::from_raw_parts(vaddr.data() as *const u8, len) }; 1721496ba7bSLoGin self_buf_guard.copy_from_slice(src_buf_guard); 1731496ba7bSLoGin } 1741496ba7bSLoGin ScmBuffer::DoubleBuffer(double_buffer) => { 1751496ba7bSLoGin let src_buf_guard = double_buffer.lock(); 1761496ba7bSLoGin self_buf_guard.copy_from_slice(src_buf_guard.as_ref()); 1771496ba7bSLoGin } 1781496ba7bSLoGin }; 179abe3a6eaShanjiezhou } 180abe3a6eaShanjiezhou 1811496ba7bSLoGin ScmBuffer::DoubleBuffer(double_buffer) => { 1821496ba7bSLoGin let mut double_buffer_guard = double_buffer.lock(); 1831496ba7bSLoGin match &src.buf { 1841496ba7bSLoGin ScmBuffer::DeviceBuffer(vaddr) => { 1852755467cS曾俊 let len = src.buf_size() / core::mem::size_of::<u8>(); 1861496ba7bSLoGin double_buffer_guard.as_mut().copy_from_slice(unsafe { 1872755467cS曾俊 core::slice::from_raw_parts(vaddr.data() as *const u8, len) 1881496ba7bSLoGin }); 1891496ba7bSLoGin } 1901496ba7bSLoGin ScmBuffer::DoubleBuffer(double_buffer) => { 1911496ba7bSLoGin let x = double_buffer.lock(); 1921496ba7bSLoGin double_buffer_guard.as_mut().copy_from_slice(x.as_ref()); 1931496ba7bSLoGin } 1941496ba7bSLoGin }; 195abe3a6eaShanjiezhou } 196abe3a6eaShanjiezhou } 197abe3a6eaShanjiezhou } 198abe3a6eaShanjiezhou } 1991496ba7bSLoGin 200abe3a6eaShanjiezhou #[derive(Debug, Copy, Clone, Eq, PartialEq, PartialOrd, Ord, Hash)] 201abe3a6eaShanjiezhou pub struct ScmUiFrameworkId(u32); 202abe3a6eaShanjiezhou 203abe3a6eaShanjiezhou impl ScmUiFrameworkId { 204abe3a6eaShanjiezhou /// 分配一个新的框架id 205abe3a6eaShanjiezhou pub fn new() -> Self { 206abe3a6eaShanjiezhou static MAX_ID: AtomicU32 = AtomicU32::new(0); 207abe3a6eaShanjiezhou return ScmUiFrameworkId(MAX_ID.fetch_add(1, Ordering::SeqCst)); 208abe3a6eaShanjiezhou } 209abe3a6eaShanjiezhou } 210abe3a6eaShanjiezhou #[allow(dead_code)] 211abe3a6eaShanjiezhou #[derive(Debug, Clone)] 212abe3a6eaShanjiezhou pub struct ScmUiFrameworkMetadata { 213abe3a6eaShanjiezhou id: ScmUiFrameworkId, 214abe3a6eaShanjiezhou name: String, 215abe3a6eaShanjiezhou framework_type: ScmFramworkType, 216abe3a6eaShanjiezhou pub buf_info: ScmBufferInfo, 217abe3a6eaShanjiezhou } 218abe3a6eaShanjiezhou 219abe3a6eaShanjiezhou impl ScmUiFrameworkMetadata { 220abe3a6eaShanjiezhou pub fn new(name: String, framework_type: ScmFramworkType) -> Self { 221abe3a6eaShanjiezhou match framework_type { 222abe3a6eaShanjiezhou ScmFramworkType::Text => { 223abe3a6eaShanjiezhou let result = ScmUiFrameworkMetadata { 224abe3a6eaShanjiezhou id: ScmUiFrameworkId::new(), 225abe3a6eaShanjiezhou name, 226abe3a6eaShanjiezhou framework_type: ScmFramworkType::Text, 2271496ba7bSLoGin buf_info: ScmBufferInfo::new( 2281496ba7bSLoGin ScmBufferFlag::SCM_BF_TEXT | ScmBufferFlag::SCM_BF_DB, 2291496ba7bSLoGin ) 2301496ba7bSLoGin .unwrap(), 231abe3a6eaShanjiezhou }; 232abe3a6eaShanjiezhou 233abe3a6eaShanjiezhou return result; 234abe3a6eaShanjiezhou } 235abe3a6eaShanjiezhou ScmFramworkType::Gui => todo!(), 236abe3a6eaShanjiezhou ScmFramworkType::Unused => todo!(), 237abe3a6eaShanjiezhou } 238abe3a6eaShanjiezhou } 239abe3a6eaShanjiezhou pub fn buf_info(&self) -> ScmBufferInfo { 240abe3a6eaShanjiezhou return self.buf_info.clone(); 241abe3a6eaShanjiezhou } 242abe3a6eaShanjiezhou pub fn set_buf_info(&mut self, buf_info: ScmBufferInfo) { 243abe3a6eaShanjiezhou self.buf_info = buf_info; 244abe3a6eaShanjiezhou } 245abe3a6eaShanjiezhou } 246abe3a6eaShanjiezhou pub trait ScmUiFramework: Sync + Send + Debug { 247abe3a6eaShanjiezhou // 安装ui框架的回调函数 248abe3a6eaShanjiezhou fn install(&self) -> Result<i32, SystemError> { 2491074eb34SSamuel Dai return Err(SystemError::ENOSYS); 250abe3a6eaShanjiezhou } 251abe3a6eaShanjiezhou // 卸载ui框架的回调函数 252bd70d2d1SLoGin #[allow(dead_code)] 253abe3a6eaShanjiezhou fn uninstall(&self) -> Result<i32, SystemError> { 2541074eb34SSamuel Dai return Err(SystemError::ENOSYS); 255abe3a6eaShanjiezhou } 256abe3a6eaShanjiezhou // 启用ui框架的回调函数 257abe3a6eaShanjiezhou fn enable(&self) -> Result<i32, SystemError> { 2581074eb34SSamuel Dai return Err(SystemError::ENOSYS); 259abe3a6eaShanjiezhou } 260abe3a6eaShanjiezhou // 禁用ui框架的回调函数 261abe3a6eaShanjiezhou fn disable(&self) -> Result<i32, SystemError> { 2621074eb34SSamuel Dai return Err(SystemError::ENOSYS); 263abe3a6eaShanjiezhou } 264abe3a6eaShanjiezhou // 改变ui框架的帧缓冲区的回调函数 265abe3a6eaShanjiezhou fn change(&self, _buf: ScmBufferInfo) -> Result<i32, SystemError> { 2661074eb34SSamuel Dai return Err(SystemError::ENOSYS); 267abe3a6eaShanjiezhou } 268abe3a6eaShanjiezhou /// @brief 获取ScmUiFramework的元数据 269abe3a6eaShanjiezhou /// @return 成功:Ok(ScmUiFramework的元数据) 270abe3a6eaShanjiezhou /// 失败:Err(错误码) 271abe3a6eaShanjiezhou fn metadata(&self) -> Result<ScmUiFrameworkMetadata, SystemError> { 272abe3a6eaShanjiezhou // 若文件系统没有实现此方法,则返回“不支持” 2731074eb34SSamuel Dai return Err(SystemError::ENOSYS); 274abe3a6eaShanjiezhou } 275abe3a6eaShanjiezhou } 276abe3a6eaShanjiezhou 277abe3a6eaShanjiezhou /// 初始化屏幕控制模块 278abe3a6eaShanjiezhou /// 279abe3a6eaShanjiezhou /// ## 调用时机 280abe3a6eaShanjiezhou /// 281abe3a6eaShanjiezhou /// 该函数在内核启动的早期进行调用。调用时,内存管理模块尚未初始化。 2821a72a751SLoGin pub fn scm_init(enable_put_to_window: bool) { 283abe3a6eaShanjiezhou SCM_DOUBLE_BUFFER_ENABLED.store(false, Ordering::SeqCst); // 禁用双缓冲 2841a72a751SLoGin if enable_put_to_window { 2851a72a751SLoGin textui_enable_put_to_window(); 2861a72a751SLoGin } else { 2871a72a751SLoGin textui_disable_put_to_window(); 2881a72a751SLoGin } 2891a72a751SLoGin textui_init_no_alloc(enable_put_to_window); 290abe3a6eaShanjiezhou 291a03c4f9dSLoGin send_to_default_serial8250_port("\nfinish_scm_init\n\0".as_bytes()); 292abe3a6eaShanjiezhou } 293abe3a6eaShanjiezhou 294abe3a6eaShanjiezhou /// 启用某个ui框架,将它的帧缓冲区渲染到屏幕上 295abe3a6eaShanjiezhou /// ## 参数 296abe3a6eaShanjiezhou /// 297abe3a6eaShanjiezhou /// - framework 要启动的ui框架 298abe3a6eaShanjiezhou 299abe3a6eaShanjiezhou pub fn scm_framework_enable(framework: Arc<dyn ScmUiFramework>) -> Result<i32, SystemError> { 300abe3a6eaShanjiezhou // 获取信息 301abe3a6eaShanjiezhou let metadata = framework.metadata()?; 302abe3a6eaShanjiezhou 303abe3a6eaShanjiezhou // if metadata.buf_info.buf.is_null() { 304abe3a6eaShanjiezhou // return Err(SystemError::EINVAL); 305abe3a6eaShanjiezhou // } 306abe3a6eaShanjiezhou let mut current_framework = CURRENT_FRAMEWORK.write(); 307abe3a6eaShanjiezhou 308b5b571e0SLoGin if SCM_DOUBLE_BUFFER_ENABLED.load(Ordering::SeqCst) { 3091496ba7bSLoGin video_refresh_manager().set_refresh_target(&metadata.buf_info)?; 310abe3a6eaShanjiezhou } 311abe3a6eaShanjiezhou 3121496ba7bSLoGin framework.enable()?; 313abe3a6eaShanjiezhou current_framework.replace(framework); 314abe3a6eaShanjiezhou 315abe3a6eaShanjiezhou return Ok(0); 316abe3a6eaShanjiezhou } 317abe3a6eaShanjiezhou /// 向屏幕管理器注册UI框架 318abe3a6eaShanjiezhou /// 319abe3a6eaShanjiezhou /// ## 参数 320abe3a6eaShanjiezhou /// - framework 框架结构体 321abe3a6eaShanjiezhou 322abe3a6eaShanjiezhou pub fn scm_register(framework: Arc<dyn ScmUiFramework>) -> Result<i32, SystemError> { 323abe3a6eaShanjiezhou // 把ui框架加入链表 324abe3a6eaShanjiezhou 325abe3a6eaShanjiezhou SCM_FRAMEWORK_LIST.lock().push_back(framework.clone()); 326abe3a6eaShanjiezhou // 调用ui框架的回调函数以安装ui框架,并将其激活 327abe3a6eaShanjiezhou framework.install()?; 328abe3a6eaShanjiezhou 329abe3a6eaShanjiezhou // 如果当前还没有框架获得了屏幕的控制权,就让其拿去 330abe3a6eaShanjiezhou if CURRENT_FRAMEWORK.read().is_none() { 331abe3a6eaShanjiezhou return scm_framework_enable(framework); 332abe3a6eaShanjiezhou } 333abe3a6eaShanjiezhou return Ok(0); 334abe3a6eaShanjiezhou } 335abe3a6eaShanjiezhou 3361496ba7bSLoGin /// 屏幕管理器启用双缓冲区 3371496ba7bSLoGin #[allow(dead_code)] 3381496ba7bSLoGin pub fn scm_enable_double_buffer() -> Result<i32, SystemError> { 339abe3a6eaShanjiezhou if SCM_DOUBLE_BUFFER_ENABLED.load(Ordering::SeqCst) { 340abe3a6eaShanjiezhou // 已经开启了双缓冲区了, 直接退出 341abe3a6eaShanjiezhou return Ok(0); 342abe3a6eaShanjiezhou } 343abe3a6eaShanjiezhou let scm_list = SCM_FRAMEWORK_LIST.lock(); 344abe3a6eaShanjiezhou if scm_list.is_empty() { 345abe3a6eaShanjiezhou // scm 框架链表为空 346abe3a6eaShanjiezhou return Ok(0); 347abe3a6eaShanjiezhou } 348abe3a6eaShanjiezhou drop(scm_list); 349abe3a6eaShanjiezhou SCM_DOUBLE_BUFFER_ENABLED.store(true, Ordering::SeqCst); 350abe3a6eaShanjiezhou // 创建双缓冲区 3511496ba7bSLoGin let buf_info = ScmBufferInfo::new(ScmBufferFlag::SCM_BF_DB | ScmBufferFlag::SCM_BF_PIXEL)?; 3521496ba7bSLoGin 3531496ba7bSLoGin // 设置定时刷新的对象 3541496ba7bSLoGin video_refresh_manager() 3551496ba7bSLoGin .set_refresh_target(&buf_info) 3561496ba7bSLoGin .expect("set refresh target failed"); 3571496ba7bSLoGin 3581496ba7bSLoGin // 设置当前框架的帧缓冲区 359abe3a6eaShanjiezhou CURRENT_FRAMEWORK 360abe3a6eaShanjiezhou .write() 361abe3a6eaShanjiezhou .as_ref() 362abe3a6eaShanjiezhou .unwrap() 363abe3a6eaShanjiezhou .change(buf_info)?; 364abe3a6eaShanjiezhou // 遍历当前所有使用帧缓冲区的框架,更新为双缓冲区 365abe3a6eaShanjiezhou for framework in SCM_FRAMEWORK_LIST.lock().iter_mut() { 366abe3a6eaShanjiezhou if !(*framework).metadata()?.buf_info.is_double_buffer() { 367abe3a6eaShanjiezhou let new_buf_info = 368abe3a6eaShanjiezhou ScmBufferInfo::new(ScmBufferFlag::SCM_BF_DB | ScmBufferFlag::SCM_BF_PIXEL)?; 369abe3a6eaShanjiezhou (*framework).change(new_buf_info)?; 370abe3a6eaShanjiezhou } 371abe3a6eaShanjiezhou } 372abe3a6eaShanjiezhou // 通知显示驱动,启动双缓冲 3731496ba7bSLoGin video_refresh_manager().video_reinitialize(true)?; 374abe3a6eaShanjiezhou 375abe3a6eaShanjiezhou return Ok(0); 376abe3a6eaShanjiezhou } 3771496ba7bSLoGin 378abe3a6eaShanjiezhou /// 允许往窗口打印信息 379abe3a6eaShanjiezhou pub fn scm_enable_put_to_window() { 3801496ba7bSLoGin // mm之前要继续往窗口打印信息时,因为没有动态内存分配(textui并没有往scm注册),且使用的是textui,要直接修改textui里面的值 381abe3a6eaShanjiezhou if CURRENT_FRAMEWORK.read().is_none() { 3821a72a751SLoGin textui_enable_put_to_window(); 383abe3a6eaShanjiezhou } else { 384abe3a6eaShanjiezhou let r = CURRENT_FRAMEWORK 385abe3a6eaShanjiezhou .write() 386abe3a6eaShanjiezhou .as_ref() 387abe3a6eaShanjiezhou .unwrap() 388abe3a6eaShanjiezhou .enable() 389abe3a6eaShanjiezhou .unwrap_or_else(|e| e.to_posix_errno()); 390abe3a6eaShanjiezhou if r.is_negative() { 391a03c4f9dSLoGin send_to_default_serial8250_port("scm_enable_put_to_window() failed.\n\0".as_bytes()); 392abe3a6eaShanjiezhou } 393abe3a6eaShanjiezhou } 394abe3a6eaShanjiezhou } 395abe3a6eaShanjiezhou /// 禁止往窗口打印信息 396abe3a6eaShanjiezhou pub fn scm_disable_put_to_window() { 397abe3a6eaShanjiezhou // mm之前要停止往窗口打印信息时,因为没有动态内存分配(rwlock与otion依然能用,但是textui并没有往scm注册),且使用的是textui,要直接修改textui里面的值 398abe3a6eaShanjiezhou if CURRENT_FRAMEWORK.read().is_none() { 3991a72a751SLoGin textui_disable_put_to_window(); 400b5b571e0SLoGin assert!(!textui_is_enable_put_to_window()); 401abe3a6eaShanjiezhou } else { 402abe3a6eaShanjiezhou let r = CURRENT_FRAMEWORK 403abe3a6eaShanjiezhou .write() 404abe3a6eaShanjiezhou .as_ref() 405abe3a6eaShanjiezhou .unwrap() 406abe3a6eaShanjiezhou .disable() 407abe3a6eaShanjiezhou .unwrap_or_else(|e| e.to_posix_errno()); 408abe3a6eaShanjiezhou if r.is_negative() { 409a03c4f9dSLoGin send_to_default_serial8250_port("scm_disable_put_to_window() failed.\n\0".as_bytes()); 410abe3a6eaShanjiezhou } 411abe3a6eaShanjiezhou } 412abe3a6eaShanjiezhou } 413abe3a6eaShanjiezhou /// 当内存管理单元被初始化之后,重新处理帧缓冲区问题 4145b59005fSLoGin #[inline(never)] 4155b59005fSLoGin pub fn scm_reinit() -> Result<(), SystemError> { 416338f6903SLoGin #[cfg(target_arch = "x86_64")] 417338f6903SLoGin { 4185b59005fSLoGin let r = true_scm_reinit(); 4195b59005fSLoGin if r.is_err() { 420a03c4f9dSLoGin send_to_default_serial8250_port("scm reinit failed.\n\0".as_bytes()); 421abe3a6eaShanjiezhou } 422abe3a6eaShanjiezhou return r; 423abe3a6eaShanjiezhou } 424338f6903SLoGin 425338f6903SLoGin #[cfg(not(target_arch = "x86_64"))] 426338f6903SLoGin { 427338f6903SLoGin return Ok(()); 428338f6903SLoGin } 429338f6903SLoGin } 430338f6903SLoGin 431338f6903SLoGin #[allow(dead_code)] 4325b59005fSLoGin fn true_scm_reinit() -> Result<(), SystemError> { 4331496ba7bSLoGin video_refresh_manager() 4341496ba7bSLoGin .video_reinitialize(false) 4351496ba7bSLoGin .expect("video reinitialize failed"); 436abe3a6eaShanjiezhou 437abe3a6eaShanjiezhou // 遍历当前所有使用帧缓冲区的框架,更新地址 4381496ba7bSLoGin let device_buffer = video_refresh_manager().device_buffer().clone(); 439abe3a6eaShanjiezhou for framework in SCM_FRAMEWORK_LIST.lock().iter_mut() { 440abe3a6eaShanjiezhou if framework.metadata()?.buf_info().is_device_buffer() { 4411496ba7bSLoGin framework.change(device_buffer.clone())?; 442abe3a6eaShanjiezhou } 443abe3a6eaShanjiezhou } 444abe3a6eaShanjiezhou 445abe3a6eaShanjiezhou scm_enable_put_to_window(); 446abe3a6eaShanjiezhou 4475b59005fSLoGin return Ok(()); 448abe3a6eaShanjiezhou } 449