diff --git a/src/buffers.rs b/src/buffers.rs index f1a315d..a3b5f1b 100644 --- a/src/buffers.rs +++ b/src/buffers.rs @@ -1,15 +1,12 @@ -use crate::events::EventBus; use crate::geometry::*; use crate::lib8::interpolate::Fract8Ops; use crate::power::AsMilliwatts; use crate::render::{PixelView, Sample, Shader, Surface, Surfaces, HardwarePixel}; -use crate::task::Task; -use std::fmt::Debug; +use std::cell::RefCell; use std::ops::IndexMut; use std::sync::atomic::AtomicBool; -use std::sync::RwLock; use std::sync::{Arc, Mutex}; struct ShaderBinding { @@ -80,9 +77,9 @@ impl Surface for BufferedSurface { }); } - fn set_shader(&mut self, shader: Box) { + fn set_shader(&mut self, shader: T) { self.updater.push(SurfaceUpdate { - shader: Some(Some(shader)), + shader: Some(Some(Box::new(shader))), slot: self.slot, ..Default::default() }); @@ -143,31 +140,28 @@ impl ShaderChain { } pub fn commit(&mut self) { - let mut queue: Vec = { - let mut updates = self.updates.pending.lock().unwrap(); - std::mem::take(updates.as_mut()) - }; - for update in queue.iter_mut() { - let target_slot = &mut self.bindings[update.slot]; - if let Some(shader) = update.shader.take() { - target_slot.shader = shader; - } - if let Some(opacity) = update.opacity.take() { - target_slot.opacity = opacity; - } - if let Some(rect) = update.rect.take() { - target_slot.rect = rect; + if self.is_dirty() { + let mut queue: Vec = { + let mut updates = self.updates.pending.lock().unwrap(); + std::mem::take(updates.as_mut()) + }; + for update in queue.iter_mut() { + let target_slot = &mut self.bindings[update.slot]; + if let Some(shader) = update.shader.take() { + target_slot.shader = shader; + } + if let Some(opacity) = update.opacity.take() { + target_slot.opacity = opacity; + } + if let Some(rect) = update.rect.take() { + target_slot.rect = rect; + } } + self.updates.damaged.store(false, std::sync::atomic::Ordering::Relaxed); } - self.updates.damaged.store(false, std::sync::atomic::Ordering::Relaxed); } -} -impl Surfaces for ShaderChain { - type Error = (); - type Surface = BufferedSurface; - - fn new_surface(&mut self, area: Rectangle) -> Result { + fn new_surface(&mut self, area: Rectangle) -> Result { let next_slot = self.bindings.len(); self.bindings.push(ShaderBinding { opacity: 255, @@ -182,12 +176,12 @@ impl Surfaces for ShaderChain { } fn render_to(&self, output: &mut S, frame: usize) { - for surface in self.bindings.iter() { + for surface in &self.bindings { let opacity = surface.opacity; if opacity > 0 { - let rect = surface.rect; - let mut sample = output.sample(&rect); if let Some(ref shader) = surface.shader { + let rect = surface.rect; + let mut sample = output.sample(&rect); while let Some((virt_coords, pixel)) = sample.next() { *pixel = pixel.blend8(shader.draw(&virt_coords, frame).into(), opacity); } @@ -197,37 +191,29 @@ impl Surfaces for ShaderChain { } } -#[derive(Clone)] pub struct BufferedSurfacePool { - pool: Arc> + pool: RefCell } impl BufferedSurfacePool { pub fn new() -> Self { BufferedSurfacePool { - pool: Arc::new(RwLock::new(ShaderChain::new())) + pool: RefCell::new(ShaderChain::new()) } } } impl Surfaces for BufferedSurfacePool { type Error = (); - type Surface = ::Surface; + type Surface = BufferedSurface; fn new_surface(&mut self, area: crate::geometry::Rectangle) -> Result { - self.pool.write().unwrap().new_surface(area) + self.pool.borrow_mut().new_surface(area) } fn render_to(&self, output: &mut S, frame: usize) { - self.pool.read().unwrap().render_to(output, frame); - } -} - - -impl Task for BufferedSurfacePool { - fn on_tick(&mut self, _bus: &mut EventBus) { - if self.pool.read().unwrap().is_dirty() { - self.pool.write().unwrap().commit(); - } + let mut b = self.pool.borrow_mut(); + b.commit(); + b.render_to(output, frame); } }