From 9f5bf25b6b648e6ff42a67094c72a963b2a6a2c2 Mon Sep 17 00:00:00 2001 From: Christian Meissl Date: Thu, 6 Jan 2022 19:24:50 +0100 Subject: [PATCH] clamp the damage rect to the destination rect this fixes issues when the damage rect is greater than the destination rect, like providing i32::Max as the damage size --- src/backend/renderer/gles2/mod.rs | 15 +++++++++++---- src/utils/geometry.rs | 31 +++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/src/backend/renderer/gles2/mod.rs b/src/backend/renderer/gles2/mod.rs index 4faa4c3..7b73dee 100644 --- a/src/backend/renderer/gles2/mod.rs +++ b/src/backend/renderer/gles2/mod.rs @@ -1286,11 +1286,18 @@ impl Frame for Gles2Frame { let damage = damage .iter() .map(|rect| { + let rect = rect.to_f64(); + + let rect_constrained_loc = rect + .loc + .constrain(Rectangle::from_extemities((0f64, 0f64), dest.size.to_point())); + let rect_clamped_size = rect.size.clamp((0f64, 0f64), dest.size); + [ - rect.loc.x as f32 / dest.size.w as f32, - rect.loc.y as f32 / dest.size.h as f32, - rect.size.w as f32 / dest.size.w as f32, - rect.size.h as f32 / dest.size.h as f32, + (rect_constrained_loc.x / dest.size.w) as f32, + (rect_constrained_loc.y / dest.size.h) as f32, + (rect_clamped_size.w / dest.size.w) as f32, + (rect_clamped_size.h / dest.size.h) as f32, ] }) .flatten() diff --git a/src/utils/geometry.rs b/src/utils/geometry.rs index dc62786..b4a14a3 100644 --- a/src/utils/geometry.rs +++ b/src/utils/geometry.rs @@ -296,6 +296,23 @@ impl Point { } } +impl Point { + /// Constrain this [`Point`] within a [`Rectangle`] with the same coordinates + /// + /// The [`Point`] returned is guaranteed to be not smaller than the [`Rectangle`] + /// location and not greater than the [`Rectangle`] size. + #[inline] + pub fn constrain(self, rect: impl Into>) -> Point { + let rect = rect.into(); + + Point { + x: self.x.max(rect.loc.x).min(rect.size.w), + y: self.y.max(rect.loc.y).min(rect.size.h), + _kind: std::marker::PhantomData, + } + } +} + impl Point { /// Convert the underlying numerical type to f64 for floating point manipulations #[inline] @@ -543,6 +560,20 @@ impl Size { } } +impl Size { + /// Restrict this [`Size`] to min and max [`Size`] with the same coordinates + pub fn clamp(self, min: impl Into>, max: impl Into>) -> Size { + let min = min.into(); + let max = max.into(); + + Size { + w: self.w.max(min.w).min(max.w), + h: self.h.max(min.h).min(max.h), + _kind: std::marker::PhantomData, + } + } +} + impl Size { /// Convert the underlying numerical type to f64 for floating point manipulations #[inline]