Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 28 additions & 13 deletions src/backends/orbital.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::error::InitError;
use raw_window_handle::{HasDisplayHandle, HasWindowHandle, OrbitalWindowHandle, RawWindowHandle};
use std::{cmp, marker::PhantomData, num::NonZeroU32, slice, str};
use std::{marker::PhantomData, num::NonZeroU32, slice, str};

use crate::backend_interface::*;
use crate::{util, AlphaMode, Pixel, Rect, SoftBufferError};
Expand Down Expand Up @@ -190,15 +190,15 @@ impl BufferInterface for BufferImpl<'_> {
}
}

fn present_with_damage(self, _damage: &[Rect]) -> Result<(), SoftBufferError> {
fn present_with_damage(self, damage: &[Rect]) -> Result<(), SoftBufferError> {
match self.pixels {
Pixels::Mapping(mapping) => {
drop(mapping);
syscall::fsync(self.window_fd).expect("failed to sync orbital window");
*self.presented = true;
}
Pixels::Buffer(buffer) => {
set_buffer(self.window_fd, &buffer, self.width, self.height);
set_buffer(self.window_fd, &buffer, self.width, self.height, damage);
}
}

Expand Down Expand Up @@ -226,10 +226,21 @@ fn window_size(window_fd: usize) -> (usize, usize) {
(window_width, window_height)
}

fn set_buffer(window_fd: usize, buffer: &[Pixel], width_u32: u32, height_u32: u32) {
fn set_buffer(
window_fd: usize,
buffer: &[Pixel],
width_u32: u32,
_height_u32: u32,
damage: &[Rect],
) {
// Read the current width and size
let (window_width, window_height) = window_size(window_fd);

let Some(urect) = util::union_damage(damage) else {
syscall::fsync(window_fd).expect("failed to sync orbital window");
return;
};

{
// Map window buffer
let mut window_map =
Expand All @@ -240,16 +251,20 @@ fn set_buffer(window_fd: usize, buffer: &[Pixel], width_u32: u32, height_u32: u3
// https://docs.rs/orbclient/0.3.48/src/orbclient/color.rs.html#25-29
let window_data = unsafe { window_map.data_mut() };

// Copy each line, cropping to fit
let width = width_u32 as usize;
let height = height_u32 as usize;
let min_width = cmp::min(width, window_width);
let min_height = cmp::min(height, window_height);
for y in 0..min_height {
let offset_buffer = y * width;
let offset_data = y * window_width;
window_data[offset_data..offset_data + min_width]
.copy_from_slice(&buffer[offset_buffer..offset_buffer + min_width]);

let x = urect.x as usize;
let y = urect.y as usize;
let w = (urect.width.get() as usize).min(window_width.saturating_sub(x));
let h = (urect.height.get() as usize).min(window_height.saturating_sub(y));

for (src_row, dst_row) in buffer
.chunks_exact(width)
.zip(window_data.chunks_exact_mut(window_width))
.skip(y)
.take(h)
{
dst_row[x..x + w].copy_from_slice(&src_row[x..x + w]);
}

// Window buffer map is dropped here
Expand Down