xref: /StarryEngine/starry_server/src/core/compositor.rs (revision 731cae0674923fcc85c6e683a2eee596eb642796)
1 use std::{
2     cell::RefCell,
3     fs::File,
4     io::{Seek, SeekFrom, Write},
5     sync::Arc,
6 };
7 
8 use starry_client::base::renderer::Renderer;
9 
10 use crate::base::rect::Rect;
11 
12 use super::{starry_server, window_manager::window_manager, SCREEN_WIDTH};
13 
14 static mut COMPOSITOR: Option<Arc<Compositor>> = None;
15 
16 const FB_FILE_PATH: &str = "/dev/fb0";
17 
18 /// 获得合成渲染器实例
compositor() -> Option<Arc<Compositor>>19 pub fn compositor() -> Option<Arc<Compositor>> {
20     unsafe { COMPOSITOR.clone() }
21 }
22 
23 #[allow(dead_code)]
24 /// 合成渲染器
25 pub struct Compositor {
26     /// 待重绘的矩形区域
27     redraws: RefCell<Vec<Rect>>,
28     /// 帧缓冲文件
29     fb_file: RefCell<File>,
30 }
31 
32 #[allow(dead_code)]
33 impl Compositor {
34     /// 创建合成渲染器
new()35     pub fn new() {
36         let compositor = Compositor {
37             redraws: RefCell::new(Vec::new()),
38             fb_file: RefCell::new(
39                 File::open(FB_FILE_PATH).expect("[Error] Compositor failed to open fb file"),
40             ),
41         };
42 
43         unsafe {
44             COMPOSITOR = Some(Arc::new(compositor));
45         }
46 
47         // println!("[Init] Compositor created successfully!");
48     }
49 
50     /// TODO
51     /// 重绘所有请求的窗口
redraw_all(&self)52     pub fn redraw_all(&self) {
53         // println!("[Info] Compositor begin redraw_all...");
54         let window_manager = window_manager().unwrap();
55         let server = starry_server().unwrap();
56         let cursor_rect = window_manager.cursor_rect();
57 
58         // 对窗口排序
59         window_manager.rezbuffer();
60 
61         let mut total_redraw_rect_opt: Option<Rect> = None;
62         for original_rect in self.redraws.borrow_mut().drain(..) {
63             // 更新重绘的总矩形区域
64             if !original_rect.is_empty() {
65                 total_redraw_rect_opt = match total_redraw_rect_opt {
66                     Some(total_redraw) => Some(total_redraw.container(&original_rect)),
67                     None => Some(original_rect),
68                 }
69             }
70 
71             // 遍历所有显示窗口
72             for display in server.displays.borrow_mut().iter_mut() {
73                 let rect = original_rect.intersection(&display.screen_rect());
74                 if !rect.is_empty() {
75                     // TODO: 填充默认颜色
76 
77                     // 倒序渲染所有窗口
78                     let zbuffer = window_manager.zbuffer.borrow_mut();
79                     let len = zbuffer.len();
80                     for index in (0..len).rev() {
81                         let entry = zbuffer.get(index).unwrap();
82                         let _id = entry.0;
83                         let index = entry.2;
84                         let mut windows = window_manager.windows.borrow_mut();
85                         if let Some(window) = windows.get_mut(&index) {
86                             // TODO: 渲染窗口标题
87 
88                             // 渲染窗体
89                             window.draw(display, &rect);
90                         }
91                     }
92                 }
93 
94                 let cursor_intersect = rect.intersection(&cursor_rect);
95                 if !cursor_intersect.is_empty() {
96                     if let Some(cursor) = server
97                         .cursors
98                         .borrow_mut()
99                         .get_mut(&window_manager.cursor_i.get())
100                     {
101                         display.roi(&cursor_intersect).blend(&cursor.roi(
102                             &cursor_intersect.offset(-cursor_rect.left(), -cursor_rect.top()),
103                         ));
104                     }
105                 }
106             }
107         }
108 
109         // println!("[Info] Compositor calculate total redraw rect done!");
110 
111         // TODO
112         let mut fb = self.fb_file.borrow_mut();
113 
114         if let Some(total_redraw_rect) = total_redraw_rect_opt {
115             for display in server.displays.borrow_mut().iter_mut() {
116                 let display_redraw = total_redraw_rect.intersection(&display.screen_rect());
117                 if !display_redraw.is_empty() {
118                     for y in 0..display_redraw.height() {
119                         for x in 0..display_redraw.width() {
120                             let pixel = display.image.get_pixel(
121                                 x + display_redraw.left() - display.x,
122                                 y + display_redraw.top() - display.y,
123                             );
124                             let offset = (((y + display_redraw.top()) * SCREEN_WIDTH as i32)
125                                 + x
126                                 + display_redraw.left())
127                                 * 4;
128                             fb.seek(SeekFrom::Start(offset as u64))
129                                 .expect("Unable to seek framebuffer");
130                             fb.write_all(&pixel.to_bgra_bytes())
131                                 .expect("Unable to write framebuffer");
132                         }
133                     }
134                 }
135             }
136         }
137     }
138 
139     /// 窗口请求重绘
request_redraw(&self, rect: Rect)140     pub fn request_redraw(&self, rect: Rect) {
141         // println!("[Info] Compositor request redraw rect {:?}", rect);
142         let mut push = true;
143 
144         for rect in self.redraws.borrow_mut().iter_mut() {
145             let container = rect.container(&rect);
146             if container.area() <= rect.area() + rect.area() {
147                 *rect = container;
148                 push = false;
149             }
150         }
151 
152         if push {
153             self.redraws.borrow_mut().push(rect);
154         }
155     }
156 }
157