graphics: Unify damage clipping
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -169,7 +169,7 @@ impl Default for ControlHeader {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
#[repr(C)]
|
||||
pub struct GpuRect {
|
||||
pub x: u32,
|
||||
|
||||
@@ -16,7 +16,7 @@ use virtio_core::utils::VolatileCell;
|
||||
|
||||
use crate::*;
|
||||
|
||||
impl Into<GpuRect> for &Damage {
|
||||
impl Into<GpuRect> 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(
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user