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