1
0
Fork 0
forked from wry/wry

render: make damage visualizer slightly less inefficient

This commit is contained in:
Julian Orth 2025-07-27 15:00:09 +02:00
parent 225dda8e5b
commit e12ececca4
9 changed files with 30 additions and 19 deletions

View file

@ -160,7 +160,7 @@ impl DamageVisualizer {
let entries = &*self.entries.borrow(); let entries = &*self.entries.borrow();
let decay = self.decay.get(); let decay = self.decay.get();
let base_color = self.color.get(); let base_color = self.color.get();
let mut used = Region::empty(); let mut used = Region::default();
let dx = -cursor_rect.x1(); let dx = -cursor_rect.x1();
let dy = -cursor_rect.y1(); let dy = -cursor_rect.y1();
let decay_millis = decay.as_millis() as u64 as f32; let decay_millis = decay.as_millis() as u64 as f32;
@ -168,12 +168,12 @@ impl DamageVisualizer {
let srgb = &self.color_manager.srgb_srgb().linear; let srgb = &self.color_manager.srgb_srgb().linear;
for entry in entries.iter().rev() { for entry in entries.iter().rev() {
let region = Region::new(entry.rect); let region = Region::new(entry.rect);
let region = region.subtract(&used); let region = region.subtract_cow(&used);
if region.is_not_empty() { if region.is_not_empty() {
let age = (now - entry.time).as_millis() as u64 as f32 / decay_millis; let age = (now - entry.time).as_millis() as u64 as f32 / decay_millis;
let color = base_color * (1.0 - age); let color = base_color * (1.0 - age);
renderer.fill_boxes2(region.rects(), &color, srgb, dx, dy); renderer.fill_boxes2(region.rects(), &color, srgb, dx, dy);
used = used.union(&region); used = used.union_cow(&region).into_owned();
} }
} }
} }

View file

@ -314,7 +314,7 @@ pub trait GfxFramebuffer: Debug {
fn full_region(&self) -> Region { fn full_region(&self) -> Region {
let (width, height) = self.physical_size(); let (width, height) = self.physical_size();
Region::new2(Rect::new_sized_unchecked(0, 0, width, height)) Region::new(Rect::new_sized_unchecked(0, 0, width, height))
} }
} }

View file

@ -132,7 +132,7 @@ impl VulkanShmImage {
if tt == TransferType::Download { if tt == TransferType::Download {
return Err(VulkanError::UndefinedContents); return Err(VulkanError::UndefinedContents);
} }
damage = Region::new2(Rect::new_sized(0, 0, img.width as _, img.height as _).unwrap()); damage = Region::new(Rect::new_sized(0, 0, img.width as _, img.height as _).unwrap());
} }
let copies = &mut *data.regions.borrow_mut(); let copies = &mut *data.regions.borrow_mut();

View file

@ -146,7 +146,7 @@ impl ExtImageCopyCaptureFrameV1 {
&staging, &staging,
self.clone(), self.clone(),
mem.clone(), mem.clone(),
Region::new2(buffer.rect), Region::new(buffer.rect),
); );
match res { match res {
Ok(d) => self.session.pending_download.set(d), Ok(d) => self.session.pending_download.set(d),

View file

@ -240,7 +240,7 @@ impl WlBuffer {
*stride, *stride,
&self.client.state.cpu_worker, &self.client.state.cpu_worker,
)?; )?;
mem.access(|mem| tex.clone().sync_upload(mem, Region::new2(self.rect)))??; mem.access(|mem| tex.clone().sync_upload(mem, Region::new(self.rect)))??;
surface.shm_textures.front().tex.set(Some(tex)); surface.shm_textures.front().tex.set(Some(tex));
surface.shm_textures.front().damage.clear(); surface.shm_textures.front().damage.clear();
} }

View file

@ -49,7 +49,7 @@ impl Region {
return Self::default(); return Self::default();
} }
if rects.len() == 1 { if rects.len() == 1 {
return Self::new2(rects[0]); return Self::new(rects[0]);
} }
let rects = rects_to_bands(unsafe { mem::transmute::<&[Rect], &[RectRaw]>(rects) }); let rects = rects_to_bands(unsafe { mem::transmute::<&[Rect], &[RectRaw]>(rects) });
Self { Self {
@ -74,6 +74,20 @@ impl Region {
}) })
} }
pub fn union_cow<'a>(self: &'a Self, other: &'a Self) -> Cow<'a, Region> {
if self.extents.is_empty() {
return Cow::Borrowed(other);
}
if other.extents.is_empty() {
return Cow::Borrowed(self);
}
let rects = union(&self.rects, &other.rects);
Cow::Owned(Self {
rects,
extents: self.extents.union(other.extents),
})
}
pub fn subtract(self: &Rc<Self>, other: &Rc<Self>) -> Rc<Self> { pub fn subtract(self: &Rc<Self>, other: &Rc<Self>) -> Rc<Self> {
if self.extents.is_empty() || other.extents.is_empty() { if self.extents.is_empty() || other.extents.is_empty() {
return self.clone(); return self.clone();
@ -122,7 +136,7 @@ impl Region<u32> {
if rects.len() == 1 { if rects.len() == 1 {
let mut rect = rects[0]; let mut rect = rects[0];
rect.raw.tag = rect.raw.tag.constrain(); rect.raw.tag = rect.raw.tag.constrain();
return Self::new2(rect); return Self::new(rect);
} }
let rects = rects_to_bands_tagged(unsafe { let rects = rects_to_bands_tagged(unsafe {
mem::transmute::<&[Rect<u32>], &[RectRaw<u32>]>(rects) mem::transmute::<&[Rect<u32>], &[RectRaw<u32>]>(rects)
@ -153,11 +167,7 @@ impl<T> Region<T>
where where
T: Tag, T: Tag,
{ {
pub fn new(rect: Rect<T>) -> Rc<Self> { pub fn new(rect: Rect<T>) -> Self {
Rc::new(Self::new2(rect))
}
pub fn new2(rect: Rect<T>) -> Self {
let mut rects = SmallVec::new(); let mut rects = SmallVec::new();
rects.push(rect.raw); rects.push(rect.raw);
Self { Self {

View file

@ -8,7 +8,8 @@ fn union1() {
let r1 = Region::new(Rect::new(0, 0, 10, 10).unwrap()); let r1 = Region::new(Rect::new(0, 0, 10, 10).unwrap());
let r2_ = Region::new(Rect::new(5, 5, 15, 15).unwrap()); let r2_ = Region::new(Rect::new(5, 5, 15, 15).unwrap());
let r2 = Region::new(Rect::new(10, 10, 20, 20).unwrap()); let r2 = Region::new(Rect::new(10, 10, 20, 20).unwrap());
let r3 = r1.union(&r2).union(&r2_); let r3 = r1.union_cow(&r2);
let r3 = r3.union_cow(&r2_);
assert_eq!(r3.extents, Rect::new(0, 0, 20, 20).unwrap()); assert_eq!(r3.extents, Rect::new(0, 0, 20, 20).unwrap());
assert_eq!( assert_eq!(
&r3.rects[..], &r3.rects[..],
@ -25,7 +26,7 @@ fn union1() {
fn union2() { fn union2() {
let r1 = Region::new(Rect::new(0, 0, 10, 10).unwrap()); let r1 = Region::new(Rect::new(0, 0, 10, 10).unwrap());
let r2 = Region::new(Rect::new(0, 10, 10, 20).unwrap()); let r2 = Region::new(Rect::new(0, 10, 10, 20).unwrap());
let r3 = r1.union(&r2); let r3 = r1.union_cow(&r2);
assert_eq!(r3.extents, Rect::new(0, 0, 10, 20).unwrap()); assert_eq!(r3.extents, Rect::new(0, 0, 10, 20).unwrap());
assert_eq!(&r3.rects[..], &[Rect::new(0, 0, 10, 20).unwrap().raw,]); assert_eq!(&r3.rects[..], &[Rect::new(0, 0, 10, 20).unwrap().raw,]);
} }
@ -34,7 +35,7 @@ fn union2() {
fn subtract1() { fn subtract1() {
let r1 = Region::new(Rect::new(0, 0, 20, 20).unwrap()); let r1 = Region::new(Rect::new(0, 0, 20, 20).unwrap());
let r2 = Region::new(Rect::new(5, 5, 15, 15).unwrap()); let r2 = Region::new(Rect::new(5, 5, 15, 15).unwrap());
let r3 = r1.subtract(&r2); let r3 = r1.subtract_cow(&r2);
assert_eq!(r3.extents, Rect::new(0, 0, 20, 20).unwrap()); assert_eq!(r3.extents, Rect::new(0, 0, 20, 20).unwrap());
assert_eq!( assert_eq!(
&r3.rects[..], &r3.rects[..],

View file

@ -1302,7 +1302,7 @@ impl State {
&staging, &staging,
capture.clone(), capture.clone(),
mem.clone(), mem.clone(),
Region::new2(capture.rect.at_point(0, 0)), Region::new(capture.rect.at_point(0, 0)),
) )
.map_err(ShmScreencopyError::ReadPixels)?; .map_err(ShmScreencopyError::ReadPixels)?;
Ok(pending) Ok(pending)

View file

@ -544,7 +544,7 @@ impl CpuJob for RenderJob {
&staging, &staging,
data.clone(), data.clone(),
Rc::new(rt.data), Rc::new(rt.data),
Region::new2(Rect::new_sized_unchecked(0, 0, rt.width, rt.height)), Region::new(Rect::new_sized_unchecked(0, 0, rt.width, rt.height)),
) )
.map_err(TextError::Upload); .map_err(TextError::Upload);
if pending.is_ok() { if pending.is_ok() {