diff options
author | 2024-04-05 23:59:21 +0200 | |
---|---|---|
committer | 2024-04-05 23:59:21 +0200 | |
commit | 6d3e1d835e1688fbc58622a03a784ed25ed3f0e1 (patch) | |
tree | b1a14b0ec7b2da4368d5c98850fe9e9eebc5490a /wgpu/src/layer.rs | |
parent | 4a356cfc16f3b45d64826732009d9feeac016b28 (diff) | |
download | iced-6d3e1d835e1688fbc58622a03a784ed25ed3f0e1.tar.gz iced-6d3e1d835e1688fbc58622a03a784ed25ed3f0e1.tar.bz2 iced-6d3e1d835e1688fbc58622a03a784ed25ed3f0e1.zip |
Decouple caching from layering and simplify everything
Diffstat (limited to 'wgpu/src/layer.rs')
-rw-r--r-- | wgpu/src/layer.rs | 258 |
1 files changed, 127 insertions, 131 deletions
diff --git a/wgpu/src/layer.rs b/wgpu/src/layer.rs index d415da72..4c864cb0 100644 --- a/wgpu/src/layer.rs +++ b/wgpu/src/layer.rs @@ -8,39 +8,46 @@ use crate::quad::{self, Quad}; use crate::text::{self, Text}; use crate::triangle; -use std::cell::{self, RefCell}; -use std::rc::Rc; - -pub enum Layer<'a> { - Live(&'a Live), - Cached(Transformation, cell::Ref<'a, Cached>), +pub struct Layer { + pub bounds: Rectangle, + pub quads: quad::Batch, + pub triangles: triangle::Batch, + pub text: text::Batch, + pub images: image::Batch, } -pub enum LayerMut<'a> { - Live(&'a mut Live), - Cached(Transformation, cell::RefMut<'a, Cached>), +impl Default for Layer { + fn default() -> Self { + Self { + bounds: Rectangle::INFINITE, + quads: quad::Batch::default(), + triangles: triangle::Batch::default(), + text: text::Batch::default(), + images: image::Batch::default(), + } + } } pub struct Stack { - live: Vec<Live>, - cached: Vec<(Transformation, Rc<RefCell<Cached>>)>, - order: Vec<Kind>, + layers: Vec<Layer>, transformations: Vec<Transformation>, previous: Vec<usize>, + pending_meshes: Vec<Vec<Mesh>>, + pending_text: Vec<Vec<Text>>, current: usize, - live_count: usize, + active_count: usize, } impl Stack { pub fn new() -> Self { Self { - live: vec![Live::default()], - cached: Vec::new(), - order: vec![Kind::Live], + layers: vec![Layer::default()], transformations: vec![Transformation::IDENTITY], - previous: Vec::new(), + previous: vec![], + pending_meshes: vec![Vec::new()], + pending_text: vec![Vec::new()], current: 0, - live_count: 1, + active_count: 1, } } @@ -59,7 +66,7 @@ impl Stack { shadow_blur_radius: quad.shadow.blur_radius, }; - self.live[self.current].quads.add(quad, &background); + self.layers[self.current].quads.add(quad, &background); } pub fn draw_paragraph( @@ -77,7 +84,7 @@ impl Stack { transformation: self.transformations.last().copied().unwrap(), }; - self.live[self.current].text.push(paragraph); + self.pending_text[self.current].push(paragraph); } pub fn draw_editor( @@ -87,7 +94,7 @@ impl Stack { color: Color, clip_bounds: Rectangle, ) { - let paragraph = Text::Editor { + let editor = Text::Editor { editor: editor.downgrade(), position, color, @@ -95,7 +102,7 @@ impl Stack { transformation: self.transformation(), }; - self.live[self.current].text.push(paragraph); + self.pending_text[self.current].push(editor); } pub fn draw_text( @@ -107,12 +114,13 @@ impl Stack { ) { let transformation = self.transformation(); - let paragraph = Text::Cached { + let text = Text::Cached { content: text.content, bounds: Rectangle::new(position, text.bounds) * transformation, color, size: text.size * transformation.scale_factor(), - line_height: text.line_height, + line_height: text.line_height.to_absolute(text.size) + * transformation.scale_factor(), font: text.font, horizontal_alignment: text.horizontal_alignment, vertical_alignment: text.vertical_alignment, @@ -120,7 +128,7 @@ impl Stack { clip_bounds: clip_bounds * transformation, }; - self.live[self.current].text.push(paragraph); + self.pending_text[self.current].push(text); } pub fn draw_image( @@ -135,7 +143,7 @@ impl Stack { bounds: bounds * self.transformation(), }; - self.live[self.current].images.push(image); + self.layers[self.current].images.push(image); } pub fn draw_svg( @@ -150,7 +158,7 @@ impl Stack { bounds: bounds * self.transformation(), }; - self.live[self.current].images.push(svg); + self.layers[self.current].images.push(svg); } pub fn draw_mesh(&mut self, mut mesh: Mesh) { @@ -161,51 +169,86 @@ impl Stack { } } - self.live[self.current].meshes.push(mesh); + self.pending_meshes[self.current].push(mesh); } - pub fn draw_layer(&mut self, mut layer: Live) { - layer.transformation = layer.transformation * self.transformation(); + pub fn draw_mesh_group(&mut self, meshes: Vec<Mesh>) { + self.flush_pending(); - if self.live_count == self.live.len() { - self.live.push(layer); - } else { - self.live[self.live_count] = layer; - } + let transformation = self.transformation(); - self.live_count += 1; - self.order.push(Kind::Live); + self.layers[self.current] + .triangles + .push(triangle::Item::Group { + transformation, + meshes, + }); } - pub fn draw_cached_layer(&mut self, layer: &Rc<RefCell<Cached>>) { - self.cached.push((self.transformation(), layer.clone())); - self.order.push(Kind::Cache); + pub fn draw_mesh_cache(&mut self, cache: triangle::Cache) { + self.flush_pending(); + + let transformation = self.transformation(); + + self.layers[self.current] + .triangles + .push(triangle::Item::Cached { + transformation, + cache, + }); + } + + pub fn draw_text_group(&mut self, text: Vec<Text>) { + self.flush_pending(); + + let transformation = self.transformation(); + + self.layers[self.current].text.push(text::Item::Group { + transformation, + text, + }); + } + + pub fn draw_text_cache(&mut self, cache: text::Cache) { + self.flush_pending(); + + let transformation = self.transformation(); + + self.layers[self.current].text.push(text::Item::Cached { + transformation, + cache, + }); } - pub fn push_clip(&mut self, bounds: Option<Rectangle>) { + pub fn push_clip(&mut self, bounds: Rectangle) { self.previous.push(self.current); - self.order.push(Kind::Live); - self.current = self.live_count; - self.live_count += 1; + self.current = self.active_count; + self.active_count += 1; - let bounds = bounds.map(|bounds| bounds * self.transformation()); + let bounds = bounds * self.transformation(); - if self.current == self.live.len() { - self.live.push(Live { + if self.current == self.layers.len() { + self.layers.push(Layer { bounds, - ..Live::default() + ..Layer::default() }); + self.pending_meshes.push(Vec::new()); + self.pending_text.push(Vec::new()); } else { - self.live[self.current].bounds = bounds; + self.layers[self.current].bounds = bounds; } } pub fn pop_clip(&mut self) { + self.flush_pending(); + self.current = self.previous.pop().unwrap(); } pub fn push_transformation(&mut self, transformation: Transformation) { + self.flush_pending(); + self.transformations .push(self.transformation() * transformation); } @@ -218,109 +261,62 @@ impl Stack { self.transformations.last().copied().unwrap() } - pub fn iter_mut(&mut self) -> impl Iterator<Item = LayerMut<'_>> { - let mut live = self.live.iter_mut(); - let mut cached = self.cached.iter_mut(); - - self.order.iter().map(move |kind| match kind { - Kind::Live => LayerMut::Live(live.next().unwrap()), - Kind::Cache => { - let (transformation, layer) = cached.next().unwrap(); - let layer = layer.borrow_mut(); + pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut Layer> { + self.flush_pending(); - LayerMut::Cached(*transformation * layer.transformation, layer) - } - }) + self.layers[..self.active_count].iter_mut() } - pub fn iter(&self) -> impl Iterator<Item = Layer<'_>> { - let mut live = self.live.iter(); - let mut cached = self.cached.iter(); - - self.order.iter().map(move |kind| match kind { - Kind::Live => Layer::Live(live.next().unwrap()), - Kind::Cache => { - let (transformation, layer) = cached.next().unwrap(); - let layer = layer.borrow(); - - Layer::Cached(*transformation * layer.transformation, layer) - } - }) + pub fn iter(&self) -> impl Iterator<Item = &Layer> { + self.layers[..self.active_count].iter() } pub fn clear(&mut self) { - for live in &mut self.live[..self.live_count] { - live.bounds = None; - live.transformation = Transformation::IDENTITY; + for (live, pending_meshes) in self.layers[..self.active_count] + .iter_mut() + .zip(self.pending_meshes.iter_mut()) + { + live.bounds = Rectangle::INFINITE; live.quads.clear(); - live.meshes.clear(); + live.triangles.clear(); live.text.clear(); live.images.clear(); + pending_meshes.clear(); } self.current = 0; - self.live_count = 1; - - self.order.clear(); - self.order.push(Kind::Live); - - self.cached.clear(); + self.active_count = 1; self.previous.clear(); } -} -impl Default for Stack { - fn default() -> Self { - Self::new() - } -} + // We want to keep the allocated memory + #[allow(clippy::drain_collect)] + fn flush_pending(&mut self) { + let transformation = self.transformation(); -#[derive(Default)] -pub struct Live { - pub bounds: Option<Rectangle>, - pub transformation: Transformation, - pub quads: quad::Batch, - pub meshes: triangle::Batch, - pub text: text::Batch, - pub images: image::Batch, -} + let pending_meshes = &mut self.pending_meshes[self.current]; + if !pending_meshes.is_empty() { + self.layers[self.current] + .triangles + .push(triangle::Item::Group { + transformation, + meshes: pending_meshes.drain(..).collect(), + }); + } -impl Live { - pub fn into_cached(self) -> Cached { - Cached { - bounds: self.bounds, - transformation: self.transformation, - quads: quad::Cache::Staged(self.quads), - meshes: triangle::Cache::Staged(self.meshes), - text: text::Cache::Staged(self.text), - images: self.images, + let pending_text = &mut self.pending_text[self.current]; + if !pending_text.is_empty() { + self.layers[self.current].text.push(text::Item::Group { + transformation, + text: pending_text.drain(..).collect(), + }); } } } -#[derive(Default)] -pub struct Cached { - pub bounds: Option<Rectangle>, - pub transformation: Transformation, - pub quads: quad::Cache, - pub meshes: triangle::Cache, - pub text: text::Cache, - pub images: image::Batch, -} - -impl Cached { - pub fn update(&mut self, live: Live) { - self.bounds = live.bounds; - - self.quads.update(live.quads); - self.meshes.update(live.meshes); - self.text.update(live.text); - self.images = live.images; +impl Default for Stack { + fn default() -> Self { + Self::new() } } - -enum Kind { - Live, - Cache, -} |