From af0303f95e27737d9de8915f939b60a2bc3282ae Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 27 Apr 2023 15:10:41 +0200 Subject: Move damage tracking logic to `compositor` in `iced_tiny_skia` --- tiny_skia/src/window/compositor.rs | 54 +++++++++++++++++++++++++++----------- 1 file changed, 39 insertions(+), 15 deletions(-) (limited to 'tiny_skia/src/window/compositor.rs') diff --git a/tiny_skia/src/window/compositor.rs b/tiny_skia/src/window/compositor.rs index 7523e06f..d3dffb18 100644 --- a/tiny_skia/src/window/compositor.rs +++ b/tiny_skia/src/window/compositor.rs @@ -1,5 +1,6 @@ -use crate::core::Color; +use crate::core::{Color, Rectangle}; use crate::graphics::compositor::{self, Information, SurfaceError}; +use crate::graphics::damage; use crate::graphics::{Error, Primitive, Viewport}; use crate::{Backend, Renderer, Settings}; @@ -14,6 +15,8 @@ pub struct Surface { window: softbuffer::GraphicsContext, buffer: Vec, clip_mask: tiny_skia::Mask, + last_primitives: Vec, + last_background_color: Color, } impl crate::graphics::Compositor for Compositor { @@ -45,6 +48,8 @@ impl crate::graphics::Compositor for Compositor { buffer: vec![0; width as usize * height as usize], clip_mask: tiny_skia::Mask::new(width, height) .expect("Create clip mask"), + last_primitives: Vec::new(), + last_background_color: Color::BLACK, } } @@ -57,6 +62,8 @@ impl crate::graphics::Compositor for Compositor { surface.buffer.resize((width * height) as usize, 0); surface.clip_mask = tiny_skia::Mask::new(width, height).expect("Create clip mask"); + + surface.last_primitives.clear(); } fn fetch_information(&self) -> Information { @@ -105,28 +112,45 @@ pub fn present>( overlay: &[T], ) -> Result<(), compositor::SurfaceError> { let physical_size = viewport.physical_size(); + let scale_factor = viewport.scale_factor() as f32; + + let mut pixels = &mut tiny_skia::PixmapMut::from_bytes( + bytemuck::cast_slice_mut(&mut surface.buffer), + physical_size.width, + physical_size.height, + ) + .expect("Create pixel map"); + + let damage = if surface.last_background_color == background_color { + damage::list(&surface.last_primitives, primitives) + } else { + vec![Rectangle::with_size(viewport.logical_size())] + }; + + if damage.is_empty() { + return Ok(()); + } + + surface.last_primitives = primitives.to_vec(); + surface.last_background_color = background_color; + + let damage = damage::group(damage, scale_factor, physical_size); - let drawn = backend.draw( - &mut tiny_skia::PixmapMut::from_bytes( - bytemuck::cast_slice_mut(&mut surface.buffer), - physical_size.width, - physical_size.height, - ) - .expect("Create pixel map"), + backend.draw( + &mut pixels, &mut surface.clip_mask, primitives, viewport, + &damage, background_color, overlay, ); - if drawn { - surface.window.set_buffer( - &surface.buffer, - physical_size.width as u16, - physical_size.height as u16, - ); - } + surface.window.set_buffer( + &surface.buffer, + physical_size.width as u16, + physical_size.height as u16, + ); Ok(()) } -- cgit