diff --git a/graphics/vesad/src/screen.rs b/graphics/vesad/src/screen.rs index d4a26c07c2..765de4ff3d 100644 --- a/graphics/vesad/src/screen.rs +++ b/graphics/vesad/src/screen.rs @@ -120,23 +120,26 @@ impl GraphicScreen { pub fn sync(&mut self, framebuffer: &mut FrameBuffer, sync_rects: &[Damage]) { for sync_rect in sync_rects { - let x = sync_rect.x.try_into().unwrap_or(0); - let y = sync_rect.y.try_into().unwrap_or(0); - let w = sync_rect.width.try_into().unwrap_or(0); - let h = sync_rect.height.try_into().unwrap_or(0); + let sync_rect = sync_rect.clip( + self.height.try_into().unwrap(), + self.width.try_into().unwrap(), + ); - let start_y = cmp::min(self.height, y); - let end_y = cmp::min(self.height, y + h); + let start_x: usize = sync_rect.x.try_into().unwrap_or(0); + let start_y: usize = sync_rect.y.try_into().unwrap_or(0); + let w: usize = sync_rect.width.try_into().unwrap_or(0); + let h: usize = sync_rect.height.try_into().unwrap_or(0); - let start_x = cmp::min(self.width, x); - let row_pixel_count = cmp::min(self.width, x + w) - start_x; + let end_y = start_y + h; + + let row_pixel_count = w; let mut offscreen_ptr = self.offscreen.as_mut_ptr(); let mut onscreen_ptr = framebuffer.onscreen as *mut u32; // FIXME use as_mut_ptr once stable unsafe { - offscreen_ptr = offscreen_ptr.add(y * self.width + start_x); - onscreen_ptr = onscreen_ptr.add(y * framebuffer.stride + start_x); + offscreen_ptr = offscreen_ptr.add(start_y * self.width + start_x); + onscreen_ptr = onscreen_ptr.add(start_y * framebuffer.stride + start_x); let mut rows = end_y - start_y; while rows > 0 { diff --git a/graphics/virtio-gpud/src/main.rs b/graphics/virtio-gpud/src/main.rs index ab36a1048e..dcb33958f1 100644 --- a/graphics/virtio-gpud/src/main.rs +++ b/graphics/virtio-gpud/src/main.rs @@ -169,7 +169,7 @@ impl Default for ControlHeader { } } -#[derive(Debug, Clone)] +#[derive(Debug, Copy, Clone)] #[repr(C)] pub struct GpuRect { pub x: u32, diff --git a/graphics/virtio-gpud/src/scheme.rs b/graphics/virtio-gpud/src/scheme.rs index d34c20cda1..7654291251 100644 --- a/graphics/virtio-gpud/src/scheme.rs +++ b/graphics/virtio-gpud/src/scheme.rs @@ -16,7 +16,7 @@ use virtio_core::utils::VolatileCell; use crate::*; -impl Into for &Damage { +impl Into for Damage { fn into(self) -> GpuRect { GpuRect { x: self.x as u32, @@ -199,8 +199,11 @@ impl<'a> Display<'a> { if let Some(damage) = damage { for damage in damage { - self.flush_resource(ResourceFlush::new(res_id, damage.into())) - .await?; + self.flush_resource(ResourceFlush::new( + res_id, + damage.clip(self.width as i32, self.height as i32).into(), + )) + .await?; } } else { self.flush_resource(ResourceFlush::new( diff --git a/inputd/src/lib.rs b/inputd/src/lib.rs index ca8b25750f..d73cc62d28 100644 --- a/inputd/src/lib.rs +++ b/inputd/src/lib.rs @@ -1,5 +1,6 @@ #![feature(iter_next_chunk)] +use std::cmp; use std::fs::File; use std::io::{Error, Read, Write}; use std::mem::size_of; @@ -104,3 +105,19 @@ pub struct Damage { pub width: i32, pub height: i32, } + +impl Damage { + #[must_use] + pub fn clip(mut self, width: i32, height: i32) -> Self { + // Clip damage + self.x = cmp::min(self.x, width); + if self.x + self.width > width { + self.width -= cmp::min(self.width, width - self.x); + } + self.y = cmp::min(self.y, height); + if self.y + self.height > height { + self.height = cmp::min(self.height, height - self.y); + } + self + } +}