11use crate :: error:: InitError ;
22use 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
55use crate :: backend_interface:: * ;
66use 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