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