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 /// 获得合成渲染器实例 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 /// 创建合成渲染器 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 /// 重绘所有请求的窗口 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 /// 窗口请求重绘 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