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