Skip to content

Commit 66e0e2a

Browse files
authored
Implement partial updates using damage rectangles for Orbital (#344)
1 parent b121e4f commit 66e0e2a

File tree

1 file changed

+28
-13
lines changed

1 file changed

+28
-13
lines changed

src/backends/orbital.rs

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::error::InitError;
22
use raw_window_handle::{HasDisplayHandle, HasWindowHandle, OrbitalWindowHandle, RawWindowHandle};
3-
use std::{cmp, marker::PhantomData, num::NonZeroU32, slice, str};
3+
use std::{marker::PhantomData, num::NonZeroU32, slice, str};
44

55
use crate::backend_interface::*;
66
use crate::{util, AlphaMode, Pixel, Rect, SoftBufferError};
@@ -190,15 +190,15 @@ impl BufferInterface for BufferImpl<'_> {
190190
}
191191
}
192192

193-
fn present_with_damage(self, _damage: &[Rect]) -> Result<(), SoftBufferError> {
193+
fn present_with_damage(self, damage: &[Rect]) -> Result<(), SoftBufferError> {
194194
match self.pixels {
195195
Pixels::Mapping(mapping) => {
196196
drop(mapping);
197197
syscall::fsync(self.window_fd).expect("failed to sync orbital window");
198198
*self.presented = true;
199199
}
200200
Pixels::Buffer(buffer) => {
201-
set_buffer(self.window_fd, &buffer, self.width, self.height);
201+
set_buffer(self.window_fd, &buffer, self.width, self.height, damage);
202202
}
203203
}
204204

@@ -226,10 +226,21 @@ fn window_size(window_fd: usize) -> (usize, usize) {
226226
(window_width, window_height)
227227
}
228228

229-
fn set_buffer(window_fd: usize, buffer: &[Pixel], width_u32: u32, height_u32: u32) {
229+
fn set_buffer(
230+
window_fd: usize,
231+
buffer: &[Pixel],
232+
width_u32: u32,
233+
_height_u32: u32,
234+
damage: &[Rect],
235+
) {
230236
// Read the current width and size
231237
let (window_width, window_height) = window_size(window_fd);
232238

239+
let Some(urect) = util::union_damage(damage) else {
240+
syscall::fsync(window_fd).expect("failed to sync orbital window");
241+
return;
242+
};
243+
233244
{
234245
// Map window buffer
235246
let mut window_map =
@@ -240,16 +251,20 @@ fn set_buffer(window_fd: usize, buffer: &[Pixel], width_u32: u32, height_u32: u3
240251
// https://docs.rs/orbclient/0.3.48/src/orbclient/color.rs.html#25-29
241252
let window_data = unsafe { window_map.data_mut() };
242253

243-
// Copy each line, cropping to fit
244254
let width = width_u32 as usize;
245-
let height = height_u32 as usize;
246-
let min_width = cmp::min(width, window_width);
247-
let min_height = cmp::min(height, window_height);
248-
for y in 0..min_height {
249-
let offset_buffer = y * width;
250-
let offset_data = y * window_width;
251-
window_data[offset_data..offset_data + min_width]
252-
.copy_from_slice(&buffer[offset_buffer..offset_buffer + min_width]);
255+
256+
let x = urect.x as usize;
257+
let y = urect.y as usize;
258+
let w = (urect.width.get() as usize).min(window_width.saturating_sub(x));
259+
let h = (urect.height.get() as usize).min(window_height.saturating_sub(y));
260+
261+
for (src_row, dst_row) in buffer
262+
.chunks_exact(width)
263+
.zip(window_data.chunks_exact_mut(window_width))
264+
.skip(y)
265+
.take(h)
266+
{
267+
dst_row[x..x + w].copy_from_slice(&src_row[x..x + w]);
253268
}
254269

255270
// Window buffer map is dropped here

0 commit comments

Comments
 (0)