Skip to content

Commit

Permalink
fix: improve damage tracking
Browse files Browse the repository at this point in the history
  • Loading branch information
wash2 authored and Drakulix committed Dec 12, 2024
1 parent 892c05f commit 3132767
Showing 1 changed file with 52 additions and 15 deletions.
67 changes: 52 additions & 15 deletions src/utils/iced.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@ use cosmic::{
},
Theme,
};
use iced_tiny_skia::{graphics::Viewport, Primitive};
use iced_tiny_skia::{
graphics::{damage, Viewport},
Layer,
};

use once_cell::sync::Lazy;
use ordered_float::OrderedFloat;
Expand Down Expand Up @@ -143,7 +146,7 @@ impl<P: Program> IcedProgram for ProgramWrapper<P> {
pub(crate) struct IcedElementInternal<P: Program + Send + 'static> {
// draw buffer
outputs: HashSet<Output>,
buffers: HashMap<OrderedFloat<f64>, (MemoryRenderBuffer, Option<(Vec<Primitive>, Color)>)>,
buffers: HashMap<OrderedFloat<f64>, (MemoryRenderBuffer, Option<(Vec<Layer>, Color)>)>,
pending_update: Option<Instant>,

// state
Expand Down Expand Up @@ -850,7 +853,9 @@ where
internal_ref.pending_update = None;
}
let _ = internal_ref.update(force);
if let Some((buffer, _)) = internal_ref.buffers.get_mut(&OrderedFloat(scale.x)) {
if let Some((buffer, ref mut old_layers)) =
internal_ref.buffers.get_mut(&OrderedFloat(scale.x))
{
let size: Size<i32, BufferCoords> = internal_ref
.size
.to_f64()
Expand All @@ -871,20 +876,52 @@ where
let bounds = IcedSize::new(size.w as u32, size.h as u32);
let viewport = Viewport::with_physical_size(bounds, scale.x);

let damage = vec![cosmic::iced::Rectangle::new(
cosmic::iced::Point::default(),
viewport.logical_size(),
)];

internal_ref.renderer.draw(
&mut pixels,
&mut clip_mask,
&viewport,
&damage,
background_color,
&overlay,
let current_layers = internal_ref.renderer.layers();
let mut damage: Vec<_> = old_layers
.as_ref()
.and_then(|(last_primitives, last_color)| {
(last_color == &background_color).then(|| {
damage::diff(
&last_primitives,
current_layers,
|_| {
vec![cosmic::iced::Rectangle::new(
cosmic::iced::Point::default(),
viewport.logical_size(),
)]
},
Layer::damage,
)
.into_iter()
.filter(|d| {
let width = d.width as u32;
let height = d.height as u32;

width > 1 && height > 1
})
.collect()
})
})
.unwrap_or_else(|| {
vec![cosmic::iced::Rectangle::with_size(viewport.logical_size())]
});
damage = damage::group(
damage,
cosmic::iced::Rectangle::with_size(viewport.logical_size()),
);

if !damage.is_empty() {
*old_layers = Some((current_layers.to_vec(), background_color));

internal_ref.renderer.draw(
&mut pixels,
&mut clip_mask,
&viewport,
&damage,
background_color,
&overlay,
);
}
let damage = damage
.into_iter()
.filter_map(|x| x.snap())
Expand Down

0 comments on commit 3132767

Please sign in to comment.