diff options
Diffstat (limited to 'wgpu/src/widget/canvas/layer/cached.rs')
| -rw-r--r-- | wgpu/src/widget/canvas/layer/cached.rs | 82 | 
1 files changed, 82 insertions, 0 deletions
| diff --git a/wgpu/src/widget/canvas/layer/cached.rs b/wgpu/src/widget/canvas/layer/cached.rs new file mode 100644 index 00000000..c6741372 --- /dev/null +++ b/wgpu/src/widget/canvas/layer/cached.rs @@ -0,0 +1,82 @@ +use crate::{ +    canvas::{layer::Drawable, Frame, Layer}, +    triangle, +}; + +use iced_native::Size; +use std::cell::RefCell; +use std::marker::PhantomData; +use std::sync::Arc; + +#[derive(Debug)] +pub struct Cached<T: Drawable> { +    input: PhantomData<T>, +    cache: RefCell<Cache>, +} + +#[derive(Debug)] +enum Cache { +    Empty, +    Filled { +        mesh: Arc<triangle::Mesh2D>, +        bounds: Size, +    }, +} + +impl<T> Cached<T> +where +    T: Drawable + std::fmt::Debug, +{ +    pub fn new() -> Self { +        Cached { +            input: PhantomData, +            cache: RefCell::new(Cache::Empty), +        } +    } + +    pub fn clear(&mut self) { +        *self.cache.borrow_mut() = Cache::Empty; +    } + +    pub fn with<'a>(&'a self, input: &'a T) -> impl Layer + 'a { +        Bind { +            layer: self, +            input: input, +        } +    } +} + +#[derive(Debug)] +struct Bind<'a, T: Drawable> { +    layer: &'a Cached<T>, +    input: &'a T, +} + +impl<'a, T> Layer for Bind<'a, T> +where +    T: Drawable + std::fmt::Debug, +{ +    fn draw(&self, current_bounds: Size) -> Arc<triangle::Mesh2D> { +        use std::ops::Deref; + +        if let Cache::Filled { mesh, bounds } = +            self.layer.cache.borrow().deref() +        { +            if *bounds == current_bounds { +                return mesh.clone(); +            } +        } + +        let mut frame = Frame::new(current_bounds.width, current_bounds.height); +        self.input.draw(&mut frame); + +        let mesh = Arc::new(frame.into_mesh()); + +        *self.layer.cache.borrow_mut() = Cache::Filled { +            mesh: mesh.clone(), +            bounds: current_bounds, +        }; + +        mesh +    } +} | 
