veridian_kernel/desktop/wayland/
surface.rs1#![allow(dead_code)]
7
8use alloc::vec::Vec;
9
10use super::buffer::Buffer;
11use crate::error::KernelError;
12
13#[derive(Debug, Clone, Copy)]
19pub struct DamageRect {
20 pub x: i32,
21 pub y: i32,
22 pub width: u32,
23 pub height: u32,
24}
25
26#[derive(Debug, Clone)]
32pub struct SurfaceState {
33 pub buffer: Option<Buffer>,
35 pub buffer_offset: (i32, i32),
37 pub damage: Vec<DamageRect>,
39 pub opaque: Vec<DamageRect>,
41 pub input: Vec<DamageRect>,
43}
44
45impl SurfaceState {
46 fn new() -> Self {
47 Self {
48 buffer: None,
49 buffer_offset: (0, 0),
50 damage: Vec::new(),
51 opaque: Vec::new(),
52 input: Vec::new(),
53 }
54 }
55}
56
57pub struct Surface {
63 pub id: u32,
65 pub committed: SurfaceState,
67 pub pending: SurfaceState,
69 pub position: (i32, i32),
71 pub size: (u32, u32),
73 pub dirty: bool,
75 pub mapped: bool,
77 pub client_id: u32,
79}
80
81impl Surface {
82 pub fn new(id: u32) -> Self {
84 Self {
85 id,
86 committed: SurfaceState::new(),
87 pending: SurfaceState::new(),
88 position: (0, 0),
89 size: (0, 0),
90 dirty: false,
91 mapped: false,
92 client_id: 0,
93 }
94 }
95
96 pub fn with_client(id: u32, client_id: u32) -> Self {
98 let mut s = Self::new(id);
99 s.client_id = client_id;
100 s
101 }
102
103 pub fn attach_buffer(&mut self, buffer: Buffer) {
105 self.pending.buffer = Some(buffer);
106 }
107
108 pub fn attach_buffer_at(&mut self, buffer: Buffer, dx: i32, dy: i32) {
110 self.pending.buffer_offset = (dx, dy);
111 self.pending.buffer = Some(buffer);
112 }
113
114 pub fn damage(&mut self, x: i32, y: i32, width: u32, height: u32) {
116 self.pending.damage.push(DamageRect {
117 x,
118 y,
119 width,
120 height,
121 });
122 }
123
124 pub fn damage_full(&mut self) {
126 if let Some(ref buf) = self.pending.buffer {
127 self.pending.damage.push(DamageRect {
128 x: 0,
129 y: 0,
130 width: buf.width,
131 height: buf.height,
132 });
133 } else if self.size.0 > 0 && self.size.1 > 0 {
134 self.pending.damage.push(DamageRect {
135 x: 0,
136 y: 0,
137 width: self.size.0,
138 height: self.size.1,
139 });
140 }
141 }
142
143 pub fn commit(&mut self) -> Result<(), KernelError> {
147 if self.pending.buffer.is_some() {
149 self.committed.buffer = self.pending.buffer.take();
150 self.committed.buffer_offset = self.pending.buffer_offset;
151
152 if let Some(ref buf) = self.committed.buffer {
154 self.size = (buf.width, buf.height);
155 self.mapped = true;
156 }
157 }
158
159 if !self.pending.damage.is_empty() {
161 self.committed.damage.clear();
162 core::mem::swap(&mut self.committed.damage, &mut self.pending.damage);
163 self.dirty = true;
164 }
165
166 self.pending.damage.clear();
168 self.pending.buffer_offset = (0, 0);
169
170 Ok(())
171 }
172
173 pub fn has_buffer(&self) -> bool {
175 self.committed.buffer.is_some()
176 }
177
178 pub fn clear_dirty(&mut self) {
180 self.dirty = false;
181 self.committed.damage.clear();
182 }
183}
184
185#[cfg(test)]
186mod tests {
187 use super::*;
188 use crate::graphics::PixelFormat;
189
190 #[test]
191 fn test_surface_lifecycle() {
192 let mut surface = Surface::new(1);
193 assert!(!surface.mapped);
194 assert!(!surface.dirty);
195
196 let buf = Buffer::new(1, 640, 480, PixelFormat::Xrgb8888);
197 surface.attach_buffer(buf);
198 surface.damage(0, 0, 640, 480);
199 surface.commit().unwrap();
200
201 assert!(surface.mapped);
202 assert!(surface.dirty);
203 assert_eq!(surface.size, (640, 480));
204 }
205
206 #[test]
207 fn test_surface_clear_dirty() {
208 let mut surface = Surface::new(1);
209 let buf = Buffer::new(1, 100, 100, PixelFormat::Argb8888);
210 surface.attach_buffer(buf);
211 surface.damage(0, 0, 100, 100);
212 surface.commit().unwrap();
213 assert!(surface.dirty);
214
215 surface.clear_dirty();
216 assert!(!surface.dirty);
217 }
218}